27db420c5bed — Laurens Holst 6 years ago
neonlib: Move code shared between projects to Neon library.
23 files changed, 27 insertions(+), 2413 deletions(-)

A => .hgsub
A => .hgsubstate
M Makefile
M openmsx.tcl
M src/Application.asm
M src/Archive.asm
R src/BIOS.asm => 
M src/CLI.asm
M src/COM.asm
R src/Class.asm => 
R src/DOS.asm => 
R src/FileReader.asm => 
R src/FileWriter.asm => 
R src/Heap.asm => 
R src/HeapTest.asm => 
R src/Macros.asm => 
R src/NullWriter.asm => 
R src/System.asm => 
M src/deflate/Inflate.asm
R src/deflate/Reader.asm => 
R src/deflate/Writer.asm => 
R src/deflate/WriterTest.asm => 
R tools/profile.tcl => 
A => .hgsub +1 -0
@@ 0,0 1,1 @@ 
+lib/neonlib = ../neonlib

          
A => .hgsubstate +1 -0
@@ 0,0 1,1 @@ 
+d474049c9adcda6766697b0e4199bb0ea4da9b25 lib/neonlib

          
M Makefile +1 -1
@@ 1,7 1,7 @@ 
 all:
 	mkdir -p gen bin
 	node tools/gencrctable.js > gen/crctable.asm
-	java -jar tools/glass.jar -I gen src/COM.asm bin/gunzip.com bin/gunzip.sym
+	java -jar tools/glass.jar -I gen -I lib/neonlib/src src/COM.asm bin/gunzip.com bin/gunzip.sym
 
 dist: all
 	cp README.md CHANGES.md LICENSE bin/

          
M openmsx.tcl +1 -1
@@ 1,4 1,4 @@ 
-source tools/profile.tcl
+source lib/neonlib/tools/profile.tcl
 
 ext debugdevice
 set debugoutput stdout

          
M src/Application.asm +8 -10
@@ 14,9 14,12 @@ Application_template: Application
 
 ;
 Application_Main:
+	ld hl,DOS_Terminate
+	call System_SetTerminateHandler
+
 	call DOS_IsDOS2
 	ld hl,Application_dos2RequiredError
-	jp c,Application_TerminateWithError
+	jp c,System_TerminateWithError
 
 	call Application_CheckStack
 

          
@@ 99,7 102,7 @@ Application_ParseCLI:
 	ld a,l
 	or h
 	ld hl,Application_usageInstructions
-	jp z,Application_TerminateWithError
+	jp z,System_TerminateWithError
 	pop ix
 	ret
 

          
@@ 370,10 373,10 @@ Application_CheckStack:
 	ld hl,-(HEAP + HEAP_SIZE + STACK_SIZE)
 	add hl,sp
 	ld hl,Application_insufficientTPAError
-	jp nc,Application_TerminateWithError
+	jp nc,System_TerminateWithError
 	ret
 
-; a <- DOS error code
+; a = DOS error code
 Application_CheckDOSError:
 	and a
 	ret z

          
@@ 384,12 387,7 @@ Application_TerminateWithDOSError:
 	ld hl,Application_explainBuffer
 	call System_Print
 	call System_PrintCrLf
-	jp DOS_Terminate
-
-; hl <- message
-Application_TerminateWithError:
-	call System_Print
-	jp DOS_Terminate
+	jp System_TerminateWithError
 
 ;
 Application_welcome:

          
M src/Archive.asm +6 -6
@@ 83,15 83,15 @@ Archive_ReadHeader:
 	call Reader_Read_IY
 	cp Archive_SIGNATURE_1
 	ld hl,Archive_notGzipError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 	call Reader_Read_IY
 	cp Archive_SIGNATURE_2
 	ld hl,Archive_notGzipError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 	call Reader_Read_IY
 	cp Archive_DEFLATE_ID
 	ld hl,Archive_notDeflateError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 
 	call Reader_Read_IY
 	ld (ix + Archive.flags),a

          
@@ 108,7 108,7 @@ Archive_ReadHeader:
 	ld a,(ix + Archive.flags)
 	and Archive_RESERVED
 	ld hl,Archive_unknownFlagError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 
 	ld a,(ix + Archive.flags)
 	and Archive_FEXTRA

          
@@ 218,11 218,11 @@ Archive_Inflate:
 Archive_Verify:
 	call Archive_VerifyISIZE
 	ld hl,Archive_isizeMismatchError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 
 	call Archive_VerifyCRC32
 	ld hl,Archive_crc32MismatchError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 	ret
 
 ; ix = this

          
R src/BIOS.asm =>  +0 -33
@@ 1,33 0,0 @@ 
-;
-; BIOS symbols
-;
-RDSLT: equ 0CH
-WRSLT: equ 14H
-CALSLT: equ 1CH
-IDBYT0: equ 2BH
-IDBYT1: equ 2CH
-IDBYT2: equ 2DH
-IDBYT3: equ 2EH
-INITXT: equ 6CH
-CHPUT: equ 0A2H
-KILBUF: equ 156H
-CHGCPU: equ 180H
-SCNCNT: equ 0F3F6H
-LINL40: equ 0F3AEH
-TXTNAM: equ 0F3B3H
-TXTCOL: equ 0F3B5H
-TXTCGP: equ 0F3B7H
-CLIKSW: equ 0F3DBH
-STATFL: equ 0F3E7H
-NEWKEY: equ 0FBE5H
-JIFFY: equ 0FC9EH
-EXPTBL: equ 0FCC1H
-SLTTBL: equ 0FCC5H
-H.KEYI: equ 0FD9AH
-H.TIMI: equ 0FD9FH
-H.MDIN: equ 0FF75H
-H.MDTM: equ 0FF93H
-
-PPI_PORT_A: equ 0A8H
-PPI_PORT_B: equ 0A9H
-PPI_PORT_C: equ 0AAH

          
M src/CLI.asm +3 -3
@@ 83,7 83,7 @@ CLI_ParseOption: PROC
 	cp "F"
 	jr z,OptionFast
 	ld hl,CLI_unknownOptionError
-	jp Application_TerminateWithError
+	jp System_TerminateWithError
 OptionQuiet:
 	ld (ix + CLI.quiet),-1
 	inc de

          
@@ 99,7 99,7 @@ Next:
 	cp " "
 	ret z
 	ld hl,CLI_unknownOptionError
-	jp Application_TerminateWithError
+	jp System_TerminateWithError
 	ENDP
 
 ; de = buffer position

          
@@ 124,7 124,7 @@ OutputPath:
 	ld a,(ix + CLI.outputPath)
 	or (ix + CLI.outputPath + 1)
 	ld hl,CLI_multiplePathsError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 	ld (ix + CLI.outputPath),e
 	ld (ix + CLI.outputPath + 1),d
 	jp Continue

          
M src/COM.asm +4 -3
@@ 15,6 15,7 @@ STACK_SIZE: equ 100H
 
 TPA: ds 2C00H
 RAM: ds 0100H
+RAM_RESIDENT: equ RAM
 READBUFFER: ds VIRTUAL READBUFFER_SIZE
 WRITEBUFFER: ds VIRTUAL WRITEBUFFER_SIZE
 HEAP: ds VIRTUAL HEAP_SIZE

          
@@ 42,9 43,9 @@ COM_Main:
 	INCLUDE "deflate/Branch.asm"
 	INCLUDE "deflate/FixedAlphabets.asm"
 	INCLUDE "deflate/DynamicAlphabets.asm"
-	INCLUDE "deflate/Reader.asm"
-	INCLUDE "deflate/Writer.asm"
-	INCLUDE "deflate/WriterTest.asm"
+	INCLUDE "Reader.asm"
+	INCLUDE "Writer.asm"
+	INCLUDE "WriterTest.asm"
 	INCLUDE "FileReader.asm"
 	INCLUDE "FileWriter.asm"
 	INCLUDE "NullWriter.asm"

          
R src/Class.asm =>  +0 -43
@@ 1,43 0,0 @@ 
-;
-; Object to define and instantiate classes
-;
-Class: MACRO ?macro, ?template, ?heap
-	; ix <- new object
-	New:
-		push bc
-		push hl
-		ld bc,?macro._size
-	size: equ $ - 2
-		ld hl,?template
-	template: equ $ - 2
-		ld ix,?heap
-	heap: equ $ - 2
-		call Class__New
-		pop hl
-		pop bc
-		ret
-
-	; ix = object
-	Delete:
-		ld bc,?macro._size
-		ld e,ixl
-		ld d,ixh
-		ld ix,?heap
-		jp Heap_Free
-	ENDM
-
-; bc = size
-; ix = heap
-; hl = template
-Class__New:
-	push af
-	push de
-	push hl
-	call Heap_Allocate
-	ld ixl,e
-	ld ixh,d
-	pop hl
-	ldir
-	pop de
-	pop af
-	ret

          
R src/DOS.asm =>  +0 -282
@@ 1,282 0,0 @@ 
-;
-; DOS symbols
-;
-REBOOT:   equ 0H
-BDOS:     equ 5H
-DTA:      equ 80H
-HOKVLD:   equ 0FB20H
-EXTBIO:   equ 0FFCAH
-
-; MSX-DOS function calls
-_TERM0:   equ 0H
-_CONIN:   equ 1H
-_CONOUT:  equ 2H
-_AUXIN:   equ 3H
-_AUXOUT:  equ 4H
-_LSTOUT:  equ 5H
-_DIRIO:   equ 6H
-_DIRIN:   equ 7H
-_INNOE:   equ 8H
-_STROUT:  equ 9H
-_BUFIN:   equ 0AH
-_CONST:   equ 0BH
-_CPMVER:  equ 0CH
-_DSKRST:  equ 0DH
-_SELDSK:  equ 0EH
-_FOPEN:   equ 0FH
-_FCLOSE:  equ 10H
-_SFIRST:  equ 11H
-_SNEXT:   equ 12H
-_FDEL:    equ 13H
-_RDSEQ:   equ 14H
-_WRSEQ:   equ 15H
-_FMAKE:   equ 16H
-_FREN:    equ 17H
-_LOGIN:   equ 18H
-_CURDRV:  equ 19H
-_SETDTA:  equ 1AH
-_ALLOC:   equ 1BH
-_RDRND:   equ 21H
-_WRRND:   equ 22H
-_FSIZE:   equ 23H
-_SETRND:  equ 24H
-_WRBLK:   equ 26H
-_RDBLK:   equ 27H
-_WRZER:   equ 28H
-_GDATE:   equ 2AH
-_SDATE:   equ 2BH
-_GTIME:   equ 2CH
-_STIME:   equ 2DH
-_VERIFY:  equ 2EH
-_RDABS:   equ 2FH
-_WRABS:   equ 30H
-
-; MSX-DOS 2 function calls
-_DPARM:   equ 31H
-_FFIRST:  equ 40H
-_FNEXT:   equ 41H
-_FNEW:    equ 42H
-_OPEN:    equ 43H
-_CREATE:  equ 44H
-_CLOSE:   equ 45H
-_ENSURE:  equ 46H
-_DUP:     equ 47H
-_READ:    equ 48H
-_WRITE:   equ 49H
-_SEEK:    equ 4AH
-_IOCTL:   equ 4BH
-_HTEST:   equ 4CH
-_DELETE:  equ 4DH
-_RENAME:  equ 4EH
-_MOVE:    equ 4FH
-_ATTR:    equ 50H
-_FTIME:   equ 51H
-_HDELETE: equ 52H
-_HRENAME: equ 53H
-_HMOVE:   equ 54H
-_HATTR:   equ 55H
-_HFTIME:  equ 56H
-_GETDTA:  equ 57H
-_GETVFY:  equ 58H
-_GETCD:   equ 59H
-_CHDIR:   equ 5AH
-_PARSE:   equ 5BH
-_PFILE:   equ 5CH
-_CHKCHR:  equ 5DH
-_WPATH:   equ 5EH
-_FLUSH:   equ 5FH
-_FORK:    equ 60H
-_JOIN:    equ 61H
-_TERM:    equ 62H
-_DEFAB:   equ 63H
-_DEFER:   equ 64H
-_ERROR:   equ 65H
-_EXPLAIN: equ 66H
-_FORMAT:  equ 67H
-_RAMD:    equ 68H
-_BUFFER:  equ 69H
-_ASSIGN:  equ 6AH
-_GENV:    equ 6BH
-_SENV:    equ 6CH
-_FENV:    equ 6DH
-_DSKCHK:  equ 6EH
-_DOSVER:  equ 6FH
-_REDIR:   equ 70H
-
-; MSX-DOS 2 mapper support jump table
-ALL_SEG:  equ 0H
-FRE_SEG:  equ 3H
-RD_SEG:   equ 6H
-WR_SEG:   equ 9H
-CAL_SEG:  equ 0CH
-CALLS:    equ 0FH
-PUT_PH:   equ 12H
-GET_PH:   equ 15H
-PUT_P0:   equ 18H
-GET_P0:   equ 1BH
-PUT_P1:   equ 1EH
-GET_P1:   equ 21H
-PUT_P2:   equ 24H
-GET_P2:   equ 27H
-PUT_P3:   equ 2AH
-GET_P3:   equ 2DH
-
-; MSX-DOS 2 errors
-.NCOMP:   equ 0FFh
-.WRERR:   equ 0FEH
-.DISK:    equ 0FDH
-.NRDY:    equ 0FCH
-.VERFY:   equ 0FBH
-.DATA:    equ 0FAH
-.RNF:     equ 0F9H
-.WPROT:   equ 0F8H
-.UFORM:   equ 0F7H
-.NDOS:    equ 0F6H
-.WDISK:   equ 0F5H
-.WFILE:   equ 0F4H
-.SEEK:    equ 0F3H
-.IFAT:    equ 0F2H
-.NOUPB:   equ 0F1H
-.IFORM:   equ 0F0H
-.INTER:   equ 0DFH
-.NORAM:   equ 0DEH
-.IBDOS:   equ 0DCH
-.IDRV:    equ 0DBH
-.IFNM:    equ 0DAH
-.IPATH:   equ 0D9H
-.PLONG:   equ 0D8H
-.NOFIL:   equ 0D7H
-.NODIR:   equ 0D6H
-.DRFUL:   equ 0D5H
-.DKFUL:   equ 0D4H
-.DUPF:    equ 0D3H
-.DIRE:    equ 0D2H
-.FILRO:   equ 0D1H
-.DIRNE:   equ 0D0H
-.IATTR:   equ 0CFH
-.DOT:     equ 0CEH
-.SYSX:    equ 0CDH
-.DIRX:    equ 0CCH
-.FILEX:   equ 0CBH
-.FOPEN:   equ 0CAH
-.OV64K:   equ 0C9H
-.FILE:    equ 0C8H
-.EOF:     equ 0C7H
-.ACCV:    equ 0C6H
-.IPROC:   equ 0C5H
-.NHAND:   equ 0C4H
-.IHAND:   equ 0C3H
-.NOPEN:   equ 0C2H
-.IDEV:    equ 0C1H
-.IENV:    equ 0C0H
-.ELONG:   equ 0BFH
-.IDATE:   equ 0BEH
-.ITIME:   equ 0BDH
-.RAMDX:   equ 0BCH
-.NRAMD:   equ 0BBH
-.HDEAD:   equ 0BAH
-.EOL:     equ 0B9H
-.ISBFN:   equ 0B8H
-.STOP:    equ 09FH
-.CTRLC:   equ 09EH
-.ABORT:   equ 09DH
-.OUTERR:  equ 09CH
-.INERR:   equ 09BH
-.BADCOM:  equ 08FH
-.BADCM:   equ 08EH
-.BUFUL:   equ 08DH
-.OKCMD:   equ 08CH
-.IPARM:   equ 08BH
-.INP:     equ 08AH
-.NOPAR:   equ 089H
-.IOPT:    equ 088H
-.BADNO:   equ 087H
-.NOHELP:  equ 086H
-.BADVER:  equ 085H
-.NOCAT:   equ 084H
-.BADEST:  equ 083H
-.COPY:    equ 082H
-.OVDEST:  equ 081H
-
-DOS_ConsoleStatus:
-	ld c,_CONST
-	jp BDOS
-
-DOS_OpenFileHandle:
-	ld c,_OPEN
-	jp BDOS
-
-DOS_CreateFileHandle:
-	ld c,_CREATE
-	jp BDOS
-
-DOS_CloseFileHandle:
-	ld c,_CLOSE
-	jp BDOS
-
-DOS_ReadFromFileHandle:
-	ld c,_READ
-	jp BDOS
-
-DOS_WriteToFileHandle:
-	ld c,_WRITE
-	jp BDOS
-
-DOS_MoveFileHandlePointer:
-	ld c,_SEEK
-	jp BDOS
-
-; b = file handle
-; dehl = file pointer
-; a <- error
-DOS_SetFileHandlePointer:
-	ld a,0
-	call DOS_MoveFileHandlePointer
-	ret
-
-; b = file handle
-; a <- error
-; dehl <- file pointer
-DOS_GetFileHandlePointer:
-	ld hl,0
-	ld de,0
-	ld a,1
-	call DOS_MoveFileHandlePointer
-	ret
-
-DOS_ParsePathname:
-	ld c,_PARSE
-	jp BDOS
-
-DOS_Terminate:
-	ld b,1
-	jp DOS_TerminateWithErrorCode
-
-DOS_TerminateWithErrorCode:
-	ld c,_TERM
-	jp BDOS
-
-DOS_DefineAbortExitRoutine:
-	ld c,_DEFAB
-	jp BDOS
-
-DOS_ExplainErrorCode:
-	ld c,_EXPLAIN
-	jp BDOS
-
-DOS_GetEnvironmentItem:
-	ld c,_GENV
-	jp BDOS
-
-; f <- c: not DOS 2
-DOS_IsDOS2:
-	xor a
-	ld bc,0
-	ld de,0
-	ld c,_DOSVER
-	call BDOS
-	add a,-1
-	ret c
-	ld a,b
-	cp 2
-	ret

          
R src/FileReader.asm =>  +0 -54
@@ 1,54 0,0 @@ 
-;
-; Buffered sequential-access file reader
-;
-FileReader: MACRO
-	super: Reader
-	fileHandle:
-		db 0FFH
-	_size:
-	ENDM
-
-FileReader_class: Class FileReader, FileReader_template, Heap_main
-FileReader_template: FileReader
-
-; de = file path
-; hl = buffer start
-; bc = buffer size
-; ix = this
-; ix <- this
-; de <- this
-FileReader_Construct:
-	push de
-	ld de,FileReader_ReadFromFile_IY
-	call Reader_Construct
-	pop de
-	ld a,00000001B  ; read only
-	call DOS_OpenFileHandle
-	call Application_CheckDOSError
-	ld (ix + FileReader.fileHandle),b
-	ld e,ixl
-	ld d,ixh
-	ret
-
-; ix = this
-; ix <- this
-FileReader_Destruct:
-	ld b,(ix + FileReader.fileHandle)
-	call DOS_CloseFileHandle
-	call Application_CheckDOSError
-	call Reader_Destruct
-	ret
-
-; bc = byte count
-; de = buffer start
-; iy = this
-; Modifies: af, bc, de, hl
-FileReader_ReadFromFile_IY:
-	push bc
-	call DOS_ConsoleStatus  ; allow ctrl-c
-	pop hl
-	ld b,(iy + FileReader.fileHandle)
-	call DOS_ReadFromFileHandle
-	call Application_CheckDOSError
-	call DOS_ConsoleStatus  ; allow ctrl-c
-	ret

          
R src/FileWriter.asm =>  +0 -55
@@ 1,55 0,0 @@ 
-;
-; Buffered sequential-access file writer
-;
-FileWriter: MACRO
-	super: Writer
-	fileHandle:
-		db 0FFH
-	_size:
-	ENDM
-
-FileWriter_class: Class FileWriter, FileWriter_template, Heap_main
-FileWriter_template: FileWriter
-
-; de = file path
-; hl = buffer start
-; bc = buffer size
-; ix = this
-; ix <- this
-; de <- this
-FileWriter_Construct:
-	push de
-	ld de,FileWriter_WriteToFile
-	call Writer_Construct
-	pop de
-	ld a,00000010B  ; write only
-	ld b,0
-	call DOS_CreateFileHandle
-	call Application_CheckDOSError
-	ld (ix + FileWriter.fileHandle),b
-	ld e,ixl
-	ld d,ixh
-	ret
-
-; ix = this
-; ix <- this
-FileWriter_Destruct:
-	ld b,(ix + FileWriter.fileHandle)
-	call DOS_CloseFileHandle
-	call Application_CheckDOSError
-	call Writer_Destruct
-	ret
-
-; bc = byte count
-; de = buffer start
-; ix = this
-; Modifies: af, bc, de, hl
-FileWriter_WriteToFile:
-	push bc
-	call DOS_ConsoleStatus  ; allow ctrl-c
-	pop hl
-	ld b,(ix + FileWriter.fileHandle)
-	call DOS_WriteToFileHandle
-	call Application_CheckDOSError
-	call DOS_ConsoleStatus  ; allow ctrl-c
-	ret

          
R src/Heap.asm =>  +0 -416
@@ 1,416 0,0 @@ 
-;
-; A heap with allocatable space.
-;
-; Heaps must be aligned to 4 bytes, the heap size must also be multiple of 4.
-; Space on the heap is allocated in multitudes of 4 bytes to coalesce slightly
-; differently sized objects and reduce fragmentation, and to keep room for the
-; information blocks. Additionally, this is used by integrity checks.
-;
-; Free space is administered using 4-byte heap information blocks (HeapBlock),
-; which contain the size of the free space and a reference to the next block.
-; These form a linked list which is updated as space is allocated and freed.
-;
-Heap: MACRO ?start, ?size
-	start:
-		dw ?start
-	capacity:
-		dw ?size
-	end:
-		dw ?start + ?size
-	rootBlock: HeapBlock
-	_size:
-	ENDM
-
-HeapBlock: MACRO
-	space:
-		dw 0
-	next:
-		dw 0
-	ENDM
-
-; ix = this
-; ix <- this
-; de <- this
-Heap_Construct:
-	ld l,(ix + Heap.start)
-	ld h,(ix + Heap.start + 1)
-	ld c,(ix + Heap.capacity)
-	ld b,(ix + Heap.capacity + 1)
-	ld a,b
-	or c
-	call z,System_ThrowException   ; capacity must not be 0
-	ld a,l
-	and 3
-	call nz,System_ThrowException  ; start position must be multiple of 4
-	ld a,c
-	and 3
-	call nz,System_ThrowException  ; capacity must be multiple of 4
-	push hl
-	add hl,bc
-	pop hl
-	call c,System_ThrowException   ; end position must not exceed 64k
-	ld (ix + Heap.rootBlock.next),l
-	ld (ix + Heap.rootBlock.next + 1),h
-	ld (hl),c
-	inc hl
-	ld (hl),b
-	inc hl
-	ld (hl),0
-	inc hl
-	ld (hl),0
-	ld e,ixl
-	ld d,ixh
-	ret
-
-;
-; Check whether the specified space can be allocated.
-; I.e. whether a subsequent Allocate call will fail or no.
-;
-; ix = this
-; bc = space
-; f <- c: can allocate
-; Modifies: af, bc, de, hl, ix
-;
-Heap_CanAllocate: PROC
-	call Heap_CheckIntegrity
-	call Heap_RoundBC
-	ld de,Heap.rootBlock
-	add ix,de
-Loop:
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,e
-	or d       ; if end reached (null pointer)
-	ret z
-	ld ixl,e
-	ld ixh,d
-	ld l,(ix + HeapBlock.space)
-	ld h,(ix + HeapBlock.space + 1)
-	sbc hl,bc
-	jp c,Loop
-	scf
-	ret
-	ENDP
-
-;
-; Get the total amount of free heap space.
-; Note that this space may be fragmented and not allocatable in one block.
-;
-; ix = this
-; bc <- space
-; Modifies: af, bc, d, ix
-;
-Heap_GetFreeSpace: PROC
-	call Heap_CheckIntegrity
-	ld bc,0
-	ld de,Heap.rootBlock
-	add ix,de
-Loop:
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,e
-	or d       ; if end reached (null pointer)
-	ret z
-	ld ixl,e
-	ld ixh,d
-	ld a,c
-	add a,(ix + HeapBlock.space)
-	ld c,a
-	ld a,b
-	adc a,(ix + HeapBlock.space + 1)
-	ld b,a
-	jp Loop
-	ENDP
-
-;
-; Allocate a block of memory on the heap.
-;
-; ix = this
-; bc = number of bytes to allocate
-; bc <- allocated space
-; de <- allocated memory address
-; Modifies: af, bc, de, hl, ix
-; Throws out of memory exception
-;
-Heap_Allocate: PROC
-	call Heap_CheckIntegrity
-	call Heap_RoundBC
-	ld de,Heap.rootBlock
-	add ix,de
-	push de    ; dummy value
-Loop:
-	pop de     ; discard last value
-	push ix
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,e
-	or d       ; if end reached (null pointer)
-	jr z,Throw
-	ld ixl,e
-	ld ixh,d
-	ld l,(ix + HeapBlock.space)
-	ld h,(ix + HeapBlock.space + 1)
-	sbc hl,bc
-	jp c,Loop
-	jp z,ExactFit
-Fit:
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	add ix,bc
-	ld (ix + HeapBlock.space),l
-	ld (ix + HeapBlock.space + 1),h
-	ld (ix + HeapBlock.next),e
-	ld (ix + HeapBlock.next + 1),d
-	ex (sp),ix  ; ix = previous block
-	pop hl      ; hl = new block
-	ld (ix + HeapBlock.next),l
-	ld (ix + HeapBlock.next + 1),h
-	sbc hl,bc   ; de = removed block
-	ex de,hl
-	ret
-ExactFit:
-	ld l,(ix + HeapBlock.next)
-	ld h,(ix + HeapBlock.next + 1)
-	ex (sp),ix  ; ix = previous block
-	pop de      ; de = removed block
-	ld (ix + HeapBlock.next),l
-	ld (ix + HeapBlock.next + 1),h
-	ret
-Throw:
-	ld hl,Heap_outOfHeapException
-	jp System_ThrowExceptionWithMessage
-	ENDP
-
-;
-; Allocates, then clears the allocated space.
-;
-; a = clear value
-; Remaining parameters are the same as Allocate
-;
-Heap_AllocateClear: PROC
-	push af
-	call Heap_Allocate
-	pop af
-	push bc
-	push de
-	ld l,e
-	ld h,d
-	ld (de),a
-	inc de
-	dec bc
-	ld a,b
-	or c
-	jr z,Skip
-	ldir
-Skip:
-	pop de
-	pop bc
-	ret
-	ENDP
-
-;
-; Free a block of previously allocated space.
-; Please be careful to specify exactly the address and amount of memory.
-; The return values of Allocate can directly be fed into Free.
-;
-; ix = this
-; bc = number of bytes to free
-; de = memory address to free
-; Modifies: af, bc, de, hl, ix
-;
-Heap_Free: PROC
-	call Heap_CheckIntegrity
-	ex de,hl   ; hl = memory address
-	call Heap_RoundBC
-	ld de,Heap.rootBlock
-	add ix,de
-Loop:
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,e
-	or d       ; if end reached (null pointer)
-	jp z,PassedEnd
-	sbc hl,de
-	call z,System_ThrowException  ; already free
-	jp c,Passed
-	add hl,de  ; restore hl value
-	ld ixl,e   ; move to next block
-	ld ixh,d
-	jp Loop
-Passed:
-	add hl,de
-	push hl    ; check if block connects to next block
-	add hl,bc
-	sbc hl,de
-	pop hl
-	jp z,CoalesceNext
-	call nc,System_ThrowException  ; already partially free (next block)
-PassedEnd:
-CoalesceNextContinue:
-	push bc
-	push hl  ; check if block connects to previous block
-	ld c,(ix + HeapBlock.space)
-	ld b,(ix + HeapBlock.space + 1)
-	ld a,b
-	or c
-	jp z,CoalescePreviousRoot     ; if root, do not coalesce
-	and a
-	sbc hl,bc
-	ld c,ixl
-	ld b,ixh
-	sbc hl,bc
-	pop hl
-	pop bc
-	jp z,CoalescePrevious
-	call c,System_ThrowException  ; already partially free (previous block)
-CoalescePreviousRootContinue:
-	ld (ix + HeapBlock.next),l
-	ld (ix + HeapBlock.next + 1),h
-CoalescePreviousContinue:
-	ld (hl),c  ; write new block
-	inc hl
-	ld (hl),b
-	inc hl
-	ld (hl),e
-	inc hl
-	ld (hl),d
-	ret
-CoalesceNext:
-	push ix
-	ld ixl,e
-	ld ixh,d
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,c     ; add coalesced block’s space to this one
-	add a,(ix + HeapBlock.space)
-	ld c,a
-	ld a,b
-	adc a,(ix + HeapBlock.space + 1)
-	ld b,a
-	pop ix
-	jp CoalesceNextContinue
-CoalescePrevious:
-	push ix
-	pop hl
-	ld a,c
-	add a,(ix + HeapBlock.space)
-	ld c,a
-	ld a,b
-	adc a,(ix + HeapBlock.space + 1)
-	ld b,a
-	jp CoalescePreviousContinue
-CoalescePreviousRoot:
-	pop hl
-	pop bc
-	jp CoalescePreviousRootContinue
-	ENDP
-
-;
-; Checks heap integrity to guard against overflow or otherwise corrupted data.
-;
-; ix = this
-; Modifies: none
-;
-Heap_CheckIntegrity: PROC
-	push af
-	push bc
-	push de
-	push hl
-	push ix
-	ld l,(ix + Heap.start)
-	ld h,(ix + Heap.start + 1)
-	ld c,(ix + Heap.end)
-	ld b,(ix + Heap.end + 1)
-	ld de,Heap.rootBlock
-	add ix,de
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,e
-	or d       ; done if end reached (null pointer)
-	jp z,End
-	scf
-	sbc hl,de  ; check if it next comes after heap start
-	call nc,Throw
-Loop:
-	ld a,e     ; check if next is multiple of four
-	and 3
-	call nz,Throw
-	ld ixl,e
-	ld ixh,d
-	ld l,(ix + HeapBlock.space)
-	ld h,(ix + HeapBlock.space + 1)
-	ld a,l     ; check if space is not zero
-	or h
-	call z,Throw
-	ld a,l     ; check if space is multiple of four
-	and 3
-	call nz,Throw
-	and a
-	adc hl,de  ; check if space does not wrap around memory
-	call c,Throw
-	scf
-	sbc hl,bc  ; check if space end does not pass heap end
-	call nc,Throw
-	adc hl,bc
-	ld e,(ix + HeapBlock.next)
-	ld d,(ix + HeapBlock.next + 1)
-	ld a,e
-	or d       ; done stop if end reached (null pointer)
-	jp z,End
-	and a
-	sbc hl,de  ; check if next block comes after space end + 1
-	call nc,Throw
-	jp Loop
-End:
-	pop ix
-	pop hl
-	pop de
-	pop bc
-	pop af
-	ret
-Throw:
-	ld hl,Heap_integrityCheckException
-	jp System_ThrowExceptionWithMessage
-	ENDP
-
-;
-; Checks whether the specified address lies inside this heap.
-;
-; de = memory address
-; ix = this
-; f <- c: in this heap
-; Modifies: af, hl
-;
-Heap_IsInHeap:
-	ld l,(ix + Heap.start)
-	ld h,(ix + Heap.start + 1)
-	scf
-	sbc hl,de
-	ret nc
-	ld a,l
-	add a,(ix + Heap.capacity)
-	ld l,a
-	ld a,h
-	adc a,(ix + Heap.capacity + 1)
-	ret
-
-; Round bc up to a multiple of 4
-; bc = value
-; bc <- rounded value
-Heap_RoundBC:
-	ld a,c
-	or b
-	call z,System_ThrowException
-	dec bc
-	ld a,c
-	or 3
-	ld c,a
-	inc bc
-	ret
-
-;
-Heap_outOfHeapException:
-	db "Out of heap space.",0
-
-Heap_integrityCheckException:
-	db "Heap integrity check failed.",0

          
R src/HeapTest.asm =>  +0 -154
@@ 1,154 0,0 @@ 
-;
-; Heap unit tests
-;
-HeapTest_Test:
-	ld ix,HeapTest_heap
-	call Heap_Construct
-	call HeapTest_TestCanAllocate
-	call HeapTest_TestAllocationSimple
-	call HeapTest_TestAllocationRounding
-	call HeapTest_TestAllocationFragmented
-	ret
-
-HeapTest_TestCanAllocate:
-	; check available space
-	ld bc,(HeapTest_heap + Heap.capacity)
-	ld ix,HeapTest_heap
-	call Heap_CanAllocate
-	call nc,System_ThrowException
-	ld bc,(HeapTest_heap + Heap.capacity)
-	inc bc
-	ld ix,HeapTest_heap
-	call Heap_CanAllocate
-	call c,System_ThrowException
-	ret
-
-HeapTest_TestAllocationSimple:
-	; allocate entire heap
-	ld bc,(HeapTest_heap + Heap.capacity)
-	ld ix,HeapTest_heap
-	call Heap_Allocate
-	ld hl,HeapTest_heapSpace
-	and a
-	sbc hl,de
-	call nz,System_ThrowException
-	push bc
-	push de
-	ld ix,HeapTest_heap
-	call Heap_GetFreeSpace
-	ld a,b
-	or c
-	call nz,System_ThrowException
-	pop de
-	pop bc
-
-	; free allocated space
-	ld ix,HeapTest_heap
-	call Heap_Free
-	ld ix,HeapTest_heap
-	call Heap_GetFreeSpace
-	and a
-	ld hl,(HeapTest_heap + Heap.capacity)
-	sbc hl,bc
-	call nz,System_ThrowException
-	ld bc,(HeapTest_heap + Heap.capacity)
-	ld ix,HeapTest_heap
-	call Heap_CanAllocate
-	call nc,System_ThrowException
-	ret
-
-HeapTest_TestAllocationRounding:
-	ld bc,1
-	ld ix,HeapTest_heap
-	call Heap_Allocate
-	push bc
-	push de
-	and a
-	ld hl,4
-	sbc hl,bc
-	call nz,System_ThrowException
-	ld ix,HeapTest_heap
-	call Heap_GetFreeSpace
-	and a
-	ld hl,(HeapTest_heap + Heap.capacity)
-	ld de,4
-	sbc hl,de
-	sbc hl,bc
-	call nz,System_ThrowException
-	pop de
-	pop bc
-	ld ix,HeapTest_heap
-	call Heap_Free
-	ld ix,HeapTest_heap
-	call Heap_GetFreeSpace
-	and a
-	ld hl,(HeapTest_heap + Heap.capacity)
-	sbc hl,bc
-	call nz,System_ThrowException
-	ret
-
-HeapTest_TestAllocationFragmented:
-	; allocate two objects and then free the first
-	ld bc,8
-	ld ix,HeapTest_heap
-	call Heap_Allocate
-	exx
-	ld bc,8
-	ld ix,HeapTest_heap
-	call Heap_Allocate
-	push bc
-	push de
-	exx
-	ld ix,HeapTest_heap
-	call Heap_Free
-	ld ix,HeapTest_heap
-	call Heap_GetFreeSpace
-	and a
-	ld hl,(HeapTest_heap + Heap.capacity)
-	ld de,8
-	sbc hl,de
-	sbc hl,bc
-	call nz,System_ThrowException
-
-	; allocate and free remaining space
-	ld hl,-8
-	add hl,bc
-	ld c,l
-	ld b,h
-	ld ix,HeapTest_heap
-	call Heap_Allocate
-	push bc
-	push de
-	ld ix,HeapTest_heap
-	call Heap_GetFreeSpace
-	and a
-	ld hl,8
-	sbc hl,bc
-	call nz,System_ThrowException
-	pop de
-	pop bc
-	ld ix,HeapTest_heap
-	call Heap_Free
-
-	; free the last object
-	pop de
-	pop bc
-	ld ix,HeapTest_heap
-	call Heap_Free
-	ld bc,(HeapTest_heap + Heap.capacity)
-	ld ix,HeapTest_heap
-	call Heap_CanAllocate
-	call nc,System_ThrowException
-	ret
-
-;
-	SECTION RAM
-
-HeapTest_heap:
-	Heap HeapTest_heapSpace, 20H
-
-	ALIGN 4
-HeapTest_heapSpace:
-	ds 20H
-
-	ENDS

          
R src/Macros.asm =>  +0 -24
@@ 1,24 0,0 @@ 
-;
-; Pads up to a certain address
-; Gives an error message if that address is already exceeded.
-;
-PAD: MACRO ?address
-	IF $ > ?address
-		ERROR "Alignment exceeds %s"; % ?address
-	ENDIF
-	ds ?address - $
-	ENDM
-
-;
-; Pads up to the next multiple of the specified address.
-;
-ALIGN: MACRO ?boundary
-	ds ?boundary - 1 - ($ + ?boundary - 1) % ?boundary
-	ENDM
-
-;
-; Pads to ensure a section of the given size does not cross a 100H boundary.
-;
-ALIGN_FIT8: MACRO ?size
-	ds (($ + ?size - 1) >> 8) != ($ >> 8) && (100H - ($ & 0FFH)) || 0
-	ENDM

          
R src/NullWriter.asm =>  +0 -33
@@ 1,33 0,0 @@ 
-;
-; Buffered null file writer
-;
-NullWriter: MACRO
-	super: Writer
-	_size:
-	ENDM
-
-NullWriter_class: Class NullWriter, NullWriter_template, Heap_main
-NullWriter_template: NullWriter
-
-; hl = buffer start
-; bc = buffer size
-; ix = this
-; ix <- this
-; de <- this
-NullWriter_Construct:
-	ld de,NullWriter_Flush
-	call Writer_Construct
-	ret
-
-; ix = this
-; ix <- this
-NullWriter_Destruct:
-	call Writer_Destruct
-	ret
-
-; bc = byte count
-; de = buffer start
-; ix = this
-NullWriter_Flush:
-	call DOS_ConsoleStatus  ; allow ctrl-c
-	ret

          
R src/System.asm =>  +0 -361
@@ 1,361 0,0 @@ 
-;
-; System routines
-;
-
-; a = character
-; Modifies: none
-System_PrintChar:
-	exx
-	ex af,af'
-	push af
-	push bc
-	push de
-	push hl
-	ex af,af'
-	exx
-	push ix
-	push iy
-	ld iy,(EXPTBL-1)
-	ld ix,CHPUT
-	call CALSLT
-	ei
-	pop iy
-	pop ix
-	exx
-	ex af,af'
-	pop hl
-	pop de
-	pop bc
-	pop af
-	ex af,af'
-	exx
-	ret
-
-; hl = string (0-terminated)
-; Modifies: none
-System_Print:
-	push af
-	push hl
-System_Print_Loop:
-	ld a,(hl)
-	and a
-	jp z,System_Print_Done
-	call System_PrintChar
-	inc hl
-	jp System_Print_Loop
-System_Print_Done:
-	pop hl
-	pop af
-	ret
-
-; hl = string (0-terminated)
-; Modifies: none
-System_PrintLn:
-	push hl
-	call System_Print
-	call System_PrintCrLf
-	pop hl
-	ret
-
-; Modifies: none
-System_PrintCrLf:
-	push hl
-	ld hl,System_crlf
-	call System_Print
-	pop hl
-	ret
-
-; dehl = value
-; Modifies: none
-System_PrintHexDEHL:
-	ex de,hl
-	call System_PrintHexHL
-	ex de,hl
-	call System_PrintHexHL
-	ret
-
-; hl = value
-; Modifies: none
-System_PrintHexHL:
-	push af
-	ld a,h
-	call System_PrintHexA
-	ld a,l
-	call System_PrintHexA
-	pop af
-	ret
-
-; a = value
-; Modifies: none
-System_PrintHexA:
-	push af
-	rrca
-	rrca
-	rrca
-	rrca
-	and 0FH
-	call System_PrintHex
-	pop af
-	and 0FH
-	call System_PrintHex
-	ret
-
-; a = value
-; Modifies: none
-System_PrintHexANoLeading0:
-	push af
-	rrca
-	rrca
-	rrca
-	rrca
-	and 0FH
-	call nz,System_PrintHex
-	pop af
-	and 0FH
-	call System_PrintHex
-	ret
-
-; a = value (0 - 15)
-; Modifies: none
-System_PrintHex:
-	push af
-	call System_NibbleToHexDigit
-	call System_PrintChar
-	pop af
-	ret
-
-; a = value (0 - 15)
-; a <- hexadecimal character
-; Modifies: a
-System_NibbleToHexDigit:
-	cp 10
-	ccf
-	adc a,"0"
-	daa
-	ret
-
-; a = value
-; Modifies: none
-System_PrintDecA:
-	push hl
-	ld l,a
-	ld h,0
-	call System_PrintDecHL
-	pop hl
-	ret
-
-; hl = value
-; Modifies: none
-System_PrintDecHL:
-	push de
-	ld de,0
-	call System_PrintDecDEHL
-	pop de
-	ret
-
-; dehl = value
-; Modifies: none
-System_PrintDecDEHL: PROC
-	push af
-	push bc
-	push de
-	push hl
-	push iy
-	ex de,hl
-	ld iyl,e
-	ld iyh,d
-	ld a,80H
-	ld bc,-1000000000 >> 16
-	ld de,-1000000000 & 0FFFFH
-	call Digit
-	ld bc,100000000 >> 16
-	ld de,100000000 & 0FFFFH
-	call DigitReverse
-	ld bc,-10000000 >> 16
-	ld de,-10000000 & 0FFFFH
-	call Digit
-	ld bc,1000000 >> 16
-	ld de,1000000 & 0FFFFH
-	call DigitReverse
-	ld bc,-100000 >> 16
-	ld de,-100000 & 0FFFFH
-	call Digit
-	ld bc,10000 >> 16
-	ld de,10000 & 0FFFFH
-	call DigitReverse
-	ld bc,-1000 >> 16
-	ld de,-1000 & 0FFFFH
-	call Digit
-	ld bc,100 >> 16
-	ld de,100 & 0FFFFH
-	call DigitReverse
-	ld bc,-10 >> 16
-	ld de,-10 & 0FFFFH
-	call Digit
-	ld bc,1 >> 16
-	ld de,1 & 0FFFFH
-	and 7FH
-	call DigitReverse
-	pop iy
-	pop hl
-	pop de
-	pop bc
-	pop af
-	ret
-Digit:
-	and 80H
-	or "0" - 1
-Loop:
-	inc a
-	add iy,de
-	adc hl,bc
-	jp c,Loop
-	jp Print
-DigitReverse:
-	and 80H
-	or "9" + 1
-LoopReverse:
-	dec a
-	add iy,de
-	adc hl,bc
-	jp nc,LoopReverse
-	jp Print
-Print:
-	and a
-	jp p,System_PrintChar
-	cp "0" + 80H
-	ret z
-	and 7FH
-	jp System_PrintChar
-	ENDP
-
-; de = ASCIIZ string
-; a <- length, excluding the terminator
-; bc <- 0 - length, excluding the terminator
-; hl <- end of ASCIIZ string + 1
-; Modifies: af, bc, hl
-System_GetStringLength:
-	ex de,hl
-	ld e,l
-	ld d,h
-	xor a
-	ld b,a
-	ld c,a
-	cpir
-	ld a,c
-	inc bc
-	cpl
-	ret
-
-	SECTION RAM
-
-; Up to 19% faster alternative for large LDIRs (break-even at 21 loops)
-; hl = source
-; de = destination
-; bc = byte count
-System_FastLDIR: PROC
-	xor a
-	sub c
-	and 16-1
-	add a,a
-	di
-	ld (jumpOffset),a
-	ei
-	jr nz,$
-jumpOffset: equ $ - 1
-Loop:
-	REPT 16
-	ldi
-	ENDM
-	jp pe,Loop
-	ret
-	ENDP
-
-	ENDS
-
-System_EnableTurbo:
-	call System_IsTurboR
-	ret c
-	ld a,10000001B
-	ld iy,(EXPTBL-1)
-	ld ix,CHGCPU
-	call CALSLT
-	ei
-	ret
-
-System_DisableTurbo:
-	call System_IsTurboR
-	ret c
-	ld a,10000000B
-	ld iy,(EXPTBL-1)
-	ld ix,CHGCPU
-	call CALSLT
-	ei
-	ret
-
-; f <- c: not turbo R
-System_IsTurboR:
-	ld a,(EXPTBL)
-	ld hl,IDBYT2
-	call RDSLT
-	ei
-	cp 3
-	ret
-
-; hl <- current timer value, in 14 cycle increments
-; Modifies: af, hl
-System_GetHighResTimerValue:
-	in a,(0E7H)
-	ld h,a
-	in a,(0E6H)
-	ld l,a
-	and a
-	ret m
-	in a,(0E7H)
-	ld h,a
-	ret
-
-System_Stop:
-	di
-	halt
-	jp System_Stop
-
-System_ThrowException:
-	IF DEBUG
-	in a,(02EH)
-	ENDIF
-	pop de
-	call System_PrintExceptionMessage
-	jp DOS_Terminate
-
-; hl = message
-System_ThrowExceptionWithMessage:
-	IF DEBUG
-	in a,(02EH)
-	ENDIF
-	pop de
-	push hl
-	call System_PrintExceptionMessage
-	pop hl
-	call System_PrintLn
-	jp DOS_Terminate
-
-; de = address
-System_PrintExceptionMessage:
-	push de
-	ld hl,System_exceptionMessage
-	call System_Print
-	pop hl
-	dec hl
-	dec hl
-	dec hl
-	call System_PrintHexHL
-	call System_PrintCrLf
-	ret
-
-;
-System_exceptionMessage:
-	db "An exception occurred on address: ", 0
-
-System_crlf:
-	db "\r\n", 0

          
M src/deflate/Inflate.asm +2 -2
@@ 84,7 84,7 @@ Inflate_InflateBlock:
 	jp c,Inflate_InflateFixedCompressed
 	jp z,Inflate_InflateDynamicCompressed
 	ld hl,Inflate_invalidBlockTypeError
-	jp Application_TerminateWithError
+	jp System_TerminateWithError
 
 ; ix = this
 ; iy = reader

          
@@ 98,7 98,7 @@ Inflate_InflateUncompressed:
 	scf
 	adc hl,bc
 	ld hl,Inflate_invalidLengthError
-	jp nz,Application_TerminateWithError
+	jp nz,System_TerminateWithError
 	ld a,c
 	or b
 	ret z

          
R src/deflate/Reader.asm =>  +0 -482
@@ 1,482 0,0 @@ 
-;
-; Memory buffer reader
-;
-Reader: MACRO
-	; iy = this
-	; a <- value
-	Read_IY:
-		ld a,(0)
-	bufferPosition: equ $ - 2
-		inc (iy + Reader.bufferPosition)
-		ret nz
-		jp Reader_Read_IY.Continue
-
-	bufferStart:
-		dw 0
-	bufferSize:
-		dw 0
-	bufferEnd:
-		dw 0
-	filler:
-		dw System_ThrowException
-	fillPending:
-		db 0
-	bits:
-		db 0
-	_size:
-	ENDM
-
-Reader_class: Class Reader, Reader_template, Heap_main
-Reader_template: Reader
-
-; hl = buffer start
-; bc = buffer size
-; de = buffer filler
-; ix = this
-; ix <- this
-; de <- this
-Reader_Construct:
-	ld a,l  ; check if buffer is 256-byte aligned
-	or c
-	call nz,System_ThrowException
-	ld (ix + Reader.bufferStart),l
-	ld (ix + Reader.bufferStart + 1),h
-	ld (ix + Reader.bufferSize),c
-	ld (ix + Reader.bufferSize + 1),b
-	ld (ix + Reader.filler),e
-	ld (ix + Reader.filler + 1),d
-	add hl,bc
-	ld (ix + Reader.bufferEnd),l
-	ld (ix + Reader.bufferEnd + 1),h
-	dec hl  ; trap the next read
-	ld (ix + Reader.bufferPosition),l
-	ld (ix + Reader.bufferPosition + 1),h
-	ld (ix + Reader.fillPending),-1
-	ld e,ixl
-	ld d,ixh
-	ret
-
-; ix = this
-; ix <- this
-Reader_Destruct:
-	ret
-
-; iy = this
-; a <- value
-; Modifies: f
-Reader_Read_IY: PROC
-	jp iy
-Continue:
-	push af
-	ld a,(iy + Reader.bufferPosition + 1)
-	inc a
-	ld (iy + Reader.bufferPosition + 1),a
-	cp (iy + Reader.bufferEnd + 1)
-	jr z,FinishBlock
-	pop af
-	ret
-FinishBlock:
-	pop af
-	bit 0,(iy + Reader.fillPending)
-	jr nz,PendingFill
-	ld (iy + Reader.fillPending),-1
-	ld (iy + Reader.bufferPosition),0FFH
-	dec (iy + Reader.bufferPosition + 1)
-	ret
-PendingFill:
-	ld (iy + Reader.fillPending),0
-	call Reader_FinishBlock_IY
-	jp iy
-	ENDP
-
-; iy = this
-Reader_FinishBlock_IY:
-	push bc
-	push de
-	push hl
-	call Reader_FillBuffer_IY
-	pop hl
-	pop de
-	pop bc
-	ld a,(iy + Reader.bufferStart)
-	ld (iy + Reader.bufferPosition),a
-	ld a,(iy + Reader.bufferStart + 1)
-	ld (iy + Reader.bufferPosition + 1),a
-	ret
-
-; The filler is called with bc = byte count, de = buffer start
-; iy = this
-; Modifies: af, bc, de, hl
-Reader_FillBuffer_IY:
-	ld a,(iy + Reader.bufferPosition)
-	cp (iy + Reader.bufferEnd)
-	call nz,System_ThrowException
-	ld a,(iy + Reader.bufferPosition + 1)
-	cp (iy + Reader.bufferEnd + 1)
-	call nz,System_ThrowException
-	ld l,(iy + Reader.bufferPosition)
-	ld h,(iy + Reader.bufferPosition + 1)
-	ld e,(iy + Reader.bufferStart)
-	ld d,(iy + Reader.bufferStart + 1)
-	and a
-	sbc hl,de
-	ret z
-	call c,System_ThrowException
-	ld c,l
-	ld b,h
-	ld l,(iy + Reader.filler)
-	ld h,(iy + Reader.filler + 1)
-	jp hl
-
-; bc = byte count
-; de = buffer start
-; iy = this
-Reader_DefaultFiller:
-	ret
-
-; iy = this
-; de <- value
-Reader_ReadWord_IY:
-	call Reader_Read_IY
-	ld e,a
-	call Reader_Read_IY
-	ld d,a
-	ret
-
-; iy = this
-; de <- value
-Reader_ReadWordBE_IY:
-	call Reader_Read_IY
-	ld d,a
-	call Reader_Read_IY
-	ld e,a
-	ret
-
-; iy = this
-; dehl <- value
-Reader_ReadDoubleWord_IY:
-	call Reader_Read_IY
-	ld l,a
-	call Reader_Read_IY
-	ld h,a
-	call Reader_Read_IY
-	ld e,a
-	call Reader_Read_IY
-	ld d,a
-	ret
-
-; iy = reader
-; dehl <- value
-Reader_ReadDoubleWordBE_IY:
-	call Reader_Read_IY
-	ld d,a
-	call Reader_Read_IY
-	ld e,a
-	call Reader_Read_IY
-	ld h,a
-	call Reader_Read_IY
-	ld l,a
-	ret
-
-; Read block directly from buffer
-; bc = byte count requested
-; iy = this
-; bc <- byte count (<= bytes requested)
-; hl <- source address
-; Modifies: af
-Reader_ReadBlockDirect_IY: PROC
-	call Reader_FillIfNeeded_IY
-	ld l,(iy + Reader.bufferPosition)
-	ld h,(iy + Reader.bufferPosition + 1)
-	push hl
-	add hl,bc
-	jr c,Overflow
-	ld a,h
-	cp (iy + Reader.bufferEnd + 1)
-	jr nc,Overflow
-	ld (iy + Reader.bufferPosition),l
-	ld (iy + Reader.bufferPosition + 1),h
-	pop hl
-	ret
-Overflow:
-	and a
-	pop bc
-	ld l,(iy + Reader.bufferEnd)
-	ld h,(iy + Reader.bufferEnd + 1)
-	dec hl
-	ld (iy + Reader.bufferPosition),l
-	ld (iy + Reader.bufferPosition + 1),h
-	ld (iy + Reader.fillPending),-1
-	inc hl
-	and a
-	sbc hl,bc
-	ld a,l
-	ld l,c
-	ld c,a
-	ld a,h
-	ld h,b
-	ld b,a
-	ret
-	ENDP
-
-; iy = this
-Reader_FillIfNeeded_IY:
-	bit 0,(iy + Reader.fillPending)
-	ret z
-	ld (iy + Reader.fillPending),0
-	inc (iy + Reader.bufferPosition)
-	inc (iy + Reader.bufferPosition + 1)
-	call Reader_FinishBlock_IY
-	ret
-
-; bc = nr of bytes to skip
-; iy = this
-; Modifies: af, bc, hl
-Reader_Skip_IY: PROC
-Loop:
-	ld a,c
-	or b
-	ret z
-	push bc
-	call Reader_ReadBlockDirect_IY
-	pop hl
-	and a
-	sbc hl,bc
-	call c,System_ThrowException
-	ld c,l
-	ld b,h
-	jp Loop
-	ENDP
-
-; debc = nr of bytes to skip
-; iy = this
-; Modifies: af, bc, hl
-Reader_Skip32_IY: PROC
-	ld a,c
-	or b
-	call nz,Reader_Skip_IY
-	inc de
-Loop:
-	dec de
-	ld a,e
-	or d
-	ret z
-	ld bc,8000H
-	call Reader_Skip_IY
-	ld bc,8000H
-	call Reader_Skip_IY
-	jp Loop
-	ENDP
-
-; iy = this
-; f <- c: bit
-; Modifies: none
-Reader_ReadBit_IY:
-	srl (iy + Reader.bits)
-	ret nz  ; return if sentinel bit is still present
-	push bc
-	ld c,a
-	call Reader_Read_IY
-	scf  ; set sentinel bit
-	rra
-	ld (iy + Reader.bits),a
-	ld a,c
-	pop bc
-	ret
-
-; iy = this
-; c <- inline bit reader state
-Reader_PrepareReadBitInline_IY:
-	ld c,(iy + Reader.bits)
-	ret
-
-; iy = this
-; c = inline bit reader state
-Reader_FinishReadBitInline_IY:
-	ld (iy + Reader.bits),c
-	ret
-
-; c = inline bit reader state
-; iy = this
-; c <- inline bit reader state
-; f <- c: bit
-; Modifies: a
-Reader_ReadBitInline_IY: MACRO
-	srl c
-	call z,Reader_ReadBitInline_NextByte_IY  ; if sentinel bit is shifted out
-	ENDM
-
-; iy = this
-; c <- inline bit reader state
-; f <- c: bit
-; Modifies: a
-Reader_ReadBitInline_NextByte_IY:
-	call Reader_Read_IY
-	scf  ; set sentinel bit
-	rra
-	ld c,a
-	ret
-
-; iy = this
-; c = inline bit reader state
-; c <- inline bit reader state
-; f <- c: bit
-; Modifies: b
-Reader_ReadBitInline_B_IY: MACRO
-	srl c
-	call z,Reader_ReadBitInline_B_NextByte_IY  ; if sentinel bit is shifted out
-	ENDM
-
-; iy = this
-; c <- inline bit reader state
-; f <- c: bit
-; Modifies: b
-Reader_ReadBitInline_B_NextByte_IY:
-	ld b,a
-	call Reader_Read_IY
-	scf  ; set sentinel bit
-	rra
-	ld c,a
-	ld a,b
-	ret
-
-; c = inline bit reader state
-; a <- value
-; c <- inline bit reader state
-; Modifies: b
-Reader_ReadBitsInline_1_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rla
-	ret
-
-Reader_ReadBitsInline_2_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rla
-	rla
-	ret
-
-Reader_ReadBitsInline_3_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rla
-	rla
-	rla
-	ret
-
-Reader_ReadBitsInline_4_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rla
-	rla
-	rla
-	rla
-	ret
-
-Reader_ReadBitsInline_5_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	rra
-	rra
-	rra
-	ret
-
-Reader_ReadBitsInline_6_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	rra
-	rra
-	ret
-
-Reader_ReadBitsInline_7_IY:
-	xor a
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	rra
-	ret
-
-Reader_ReadBitsInline_8_IY:
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	Reader_ReadBitInline_B_IY
-	rra
-	ret
-
-; b = nr of bits to read (1-8)
-; iy = this
-; a <- value
-; Modifies: af, bc
-Reader_ReadBits_IY: PROC
-	ld c,1
-	xor a
-Loop:
-	call Reader_ReadBit_IY
-	jr nc,Zero
-	add a,c
-Zero:
-	rlc c
-	djnz Loop
-	ret
-	ENDP
-
-; iy = this
-Reader_Align_IY:
-	ld (iy + Reader.bits),0
-	ret

          
R src/deflate/Writer.asm =>  +0 -345
@@ 1,345 0,0 @@ 
-;
-; Memory buffer writer
-;
-Writer: MACRO
-	; a = value
-	; hl = return address
-	; ix = this
-	Write:
-		ld (0),a
-	bufferPosition: equ $ - 2
-		inc (ix + Writer.bufferPosition)
-		jr z,Write_Continue  ; unlikely
-		jp hl
-	Write_Continue:
-		push hl
-		jp Writer_Write.Continue
-
-	bufferStart:
-		dw 0
-	bufferSize:
-		dw 0
-	bufferEnd:
-		dw 0
-	bufferEndCopyMargin:
-		db 0
-	flusher:
-		dw System_ThrowException
-	count:
-		dd 0
-	_size:
-	ENDM
-
-Writer_class: Class Writer, Writer_template, Heap_main
-Writer_template: Writer
-
-; hl = buffer start
-; bc = buffer size
-; de = buffer flusher
-; ix = this
-; ix <- this
-; de <- this
-Writer_Construct:
-	ld a,l  ; check if buffer is 256-byte aligned
-	or c
-	call nz,System_ThrowException
-	ld (ix + Writer.bufferStart),l
-	ld (ix + Writer.bufferStart + 1),h
-	ld (ix + Writer.bufferSize),c
-	ld (ix + Writer.bufferSize + 1),b
-	ld (ix + Writer.flusher),e
-	ld (ix + Writer.flusher + 1),d
-	ld (ix + Writer.bufferPosition),l
-	ld (ix + Writer.bufferPosition + 1),h
-	add hl,bc
-	ld (ix + Writer.bufferEnd),l
-	ld (ix + Writer.bufferEnd + 1),h
-	dec h
-	dec h
-	dec h
-	ld (ix + Writer.bufferEndCopyMargin),h
-	ld e,ixl
-	ld d,ixh
-	ret
-
-; ix = this
-; ix <- this
-Writer_Destruct:
-	ret
-
-; a = value
-; ix = this
-; Modifies: hl
-Writer_WriteInline_JumpHL: MACRO
-	jp ix
-	ENDM
-
-; a = value
-; ix = this
-; Modifies: f, hl
-Writer_Write: PROC
-	pop hl
-	Writer_WriteInline_JumpHL
-Continue:
-	push af
-	ld a,(ix + Writer.bufferPosition + 1)
-	inc a
-	ld (ix + Writer.bufferPosition + 1),a
-	cp (ix + Writer.bufferEnd + 1)
-	call z,Writer_FinishBlock
-	pop af
-	ret
-	ENDP
-
-; bc = byte count (range 3-258)
-; hl = -distance
-; ix = this
-; Modifies: af, bc, de, hl
-Writer_Copy: PROC
-	ld e,(ix + Writer.bufferPosition)
-	ld d,(ix + Writer.bufferPosition + 1)
-	add hl,de
-	ld a,h
-	jr nc,Wrap
-	cp (ix + Writer.bufferStart + 1)
-	jr c,Wrap
-	ld a,(ix + Writer.bufferEndCopyMargin)
-WrapContinue:
-	cp d  ; does the destination have a 512 byte margin without wrapping?
-	jr c,Writer_Copy_Slow
-	ldi
-	ldi
-	ldir
-	ld (ix + Writer.bufferPosition),e
-	ld (ix + Writer.bufferPosition + 1),d
-	ret
-Wrap:
-	add a,(ix + Writer.bufferSize + 1)
-	ld h,a
-	ld a,(ix + Writer.bufferEndCopyMargin)
-	cp h  ; does the source have a 512 byte margin without wrapping?
-	jp nc,WrapContinue
-	jp Writer_Copy_Slow
-	ENDP
-
-; bc = byte count
-; hl = buffer source
-; ix = this
-; Modifies: af, bc, de, hl
-Writer_Copy_Slow: PROC
-	ld e,l
-	ld d,h
-	add hl,bc
-	jr c,Split
-	ld a,h
-	cp (ix + Writer.bufferEnd + 1)
-	jp c,Writer_WriteBlock
-; hl = end address
-Split:
-	push bc
-	ld c,(ix + Writer.bufferEnd)
-	ld b,(ix + Writer.bufferEnd + 1)
-	and a
-	sbc hl,bc  ; hl = bytes past end
-	ex (sp),hl
-	pop bc
-	push bc
-	sbc hl,bc  ; hl = bytes until end
-	ld c,l
-	ld b,h
-	call Writer_WriteBlock
-	pop bc
-	ld l,(ix + Writer.bufferStart)
-	ld h,(ix + Writer.bufferStart + 1)
-	ld a,b
-	or c
-	jp nz,Writer_Copy_Slow
-	ret
-	ENDP
-
-; bc = byte count
-; de = source
-; ix = this
-; Modifies: af, bc, de, hl
-Writer_WriteBlock: PROC
-	ld l,(ix + Writer.bufferPosition)
-	ld h,(ix + Writer.bufferPosition + 1)
-	add hl,bc
-	jr c,Split
-	ld a,h
-	cp (ix + Writer.bufferEnd + 1)
-	jr nc,Split
-	and a
-	sbc hl,bc
-	ex de,hl
-	call System_FastLDIR
-	ld (ix + Writer.bufferPosition),e
-	ld (ix + Writer.bufferPosition + 1),d
-	ret
-; hl = end address
-Split:
-	push bc
-	ld c,(ix + Writer.bufferEnd)
-	ld b,(ix + Writer.bufferEnd + 1)
-	and a
-	sbc hl,bc  ; hl = bytes past end
-	ld c,l
-	ld b,h
-	ex (sp),hl
-	sbc hl,bc  ; hl = bytes until end
-	ld c,l
-	ld b,h
-	ex de,hl
-	ld e,(ix + Writer.bufferPosition)
-	ld d,(ix + Writer.bufferPosition + 1)
-	call System_FastLDIR
-	ld (ix + Writer.bufferPosition),e
-	ld (ix + Writer.bufferPosition + 1),d
-	call Writer_FinishBlock
-	ex de,hl
-	ld l,(ix + Writer.bufferPosition)
-	ld h,(ix + Writer.bufferPosition + 1)
-	pop bc
-	ld a,b
-	or c
-	jp nz,Writer_WriteBlock
-	ret
-	ENDP
-
-; Write block directly into buffer
-; Afterwards, invoke Advance with the nr of bytes actually written
-; ix = this
-; bc <- max bytes to write
-; de <- destination
-; Modifies: af
-Writer_WriteBlockDirect:
-	ld e,(ix + Writer.bufferPosition)
-	ld d,(ix + Writer.bufferPosition + 1)
-	ld a,e
-	neg
-	ld c,a
-	ld a,(ix + Writer.bufferEnd + 1)
-	sbc a,d
-	ld b,a
-	ret
-
-; bc = nr of bytes to advance
-; ix = this
-; Modifies: af, bc, hl
-Writer_Advance: PROC
-	ld l,(ix + Writer.bufferPosition)
-	ld h,(ix + Writer.bufferPosition + 1)
-	add hl,bc
-	ld b,(ix + Writer.bufferEnd + 1)
-	jr c,Overflow
-	ld a,h
-	cp b
-	jr nc,Overflow
-	ld (ix + Writer.bufferPosition),l
-	ld (ix + Writer.bufferPosition + 1),h
-	ret
-Overflow:
-	ld c,0
-	ld (ix + Writer.bufferPosition),c
-	ld (ix + Writer.bufferPosition + 1),b
-	call Writer_FinishBlock
-	and a
-	sbc hl,bc
-	jr nz,Writer_Advance
-	ret
-	ENDP
-
-; bc = byte count
-; ix = this
-; iy = reader
-Writer_CopyFromReader: PROC
-Loop:
-	ld a,c
-	or b
-	ret z
-	push bc
-	call Reader_ReadBlockDirect_IY
-	push bc
-	ex de,hl
-	call Writer_WriteBlock
-	pop bc
-	pop hl
-	and a
-	sbc hl,bc
-	call c,System_ThrowException
-	ld c,l
-	ld b,h
-	jp Loop
-	ENDP
-
-; ix = this
-; hl <- buffer position
-; Modifies: af
-Writer_FinishBlock: PROC
-	push bc
-	push de
-	push hl
-	ld l,(ix + Writer.bufferPosition)
-	ld h,(ix + Writer.bufferPosition + 1)
-	ld e,(ix + Writer.bufferStart)
-	ld d,(ix + Writer.bufferStart + 1)
-	and a
-	sbc hl,de
-	call c,System_ThrowException
-	jr z,Empty
-	ld c,l
-	ld b,h
-	push bc
-	push de
-	call Writer_IncreaseCount
-	pop de
-	pop bc
-	call Writer_FlushBuffer
-Empty:
-	pop hl
-	pop de
-	pop bc
-	ld a,(ix + Writer.bufferStart)
-	ld (ix + Writer.bufferPosition),a
-	ld a,(ix + Writer.bufferStart + 1)
-	ld (ix + Writer.bufferPosition + 1),a
-	ret
-	ENDP
-
-; The flusher is called with bc = byte count, de = buffer start
-; ix = this
-; Modifies: af, bc, de, hl
-Writer_FlushBuffer:
-	ld l,(ix + Writer.flusher)
-	ld h,(ix + Writer.flusher + 1)
-	jp hl
-
-; bc = byte count
-; de = buffer start
-; ix = this
-Writer_DefaultFlusher:
-	ret
-
-; bc = byte count
-; ix = this
-; Modifies: hl
-Writer_IncreaseCount:
-	ld l,(ix + Writer.count)
-	ld h,(ix + Writer.count + 1)
-	add hl,bc
-	ld (ix + Writer.count),l
-	ld (ix + Writer.count + 1),h
-	ret nc
-	inc (ix + Writer.count + 2)
-	ret nz
-	inc (ix + Writer.count + 3)
-	ret
-
-; ix = this
-; bcde <- count bytes written
-Writer_GetCount:
-	ld e,(ix + Writer.count)
-	ld d,(ix + Writer.count + 1)
-	ld c,(ix + Writer.count + 2)
-	ld b,(ix + Writer.count + 3)
-	ret

          
R src/deflate/WriterTest.asm =>  +0 -52
@@ 1,52 0,0 @@ 
-;
-; Writer unit tests
-;
-WriterTest_Test:
-	call WriterTest_TestCount
-	ret
-
-WriterTest_TestCount: PROC
-	ld hl,WRITEBUFFER
-	ld bc,256
-	call NullWriter_class.New
-	call NullWriter_Construct
-
-	call Writer_GetCount
-	ld a,e
-	or d
-	or c
-	or b
-	call nz,System_ThrowException
-
-	ld b,58
-Loop1:
-	call Writer_Write
-	djnz Loop1
-	call Writer_FinishBlock
-	call Writer_GetCount
-	ld hl,-58
-	and a
-	adc hl,de
-	call nz,System_ThrowException
-	ld a,c
-	or b
-	call nz,System_ThrowException
-
-	ld b,200
-Loop2:
-	call Writer_Write
-	djnz Loop2
-	call Writer_FinishBlock
-	call Writer_GetCount
-	ld hl,-258
-	and a
-	adc hl,de
-	call nz,System_ThrowException
-	ld a,c
-	or b
-	call nz,System_ThrowException
-
-	call NullWriter_Destruct
-	call NullWriter_class.Delete
-	ret
-	ENDP

          
R tools/profile.tcl =>  +0 -53
@@ 1,53 0,0 @@ 
-#
-# Profiling utility
-#
-# Start profiling with out (2ch),a, end profiling with out (2dh),a.
-# Run the profile command in the openMSX console to see the result.
-#
-namespace eval profile {
-	variable time 0
-	variable start_time -1
-	variable count 0
-	variable ignored 0
-	debug set_watchpoint write_io 0x2C {} {profile::start}
-	debug set_watchpoint write_io 0x2D {} {profile::stop}
-	
-	proc start {} {
-		variable start_time
-		variable ignored
-		variable out_overhead
-		set out_cycles [expr {"[cpuregs::get_active_cpu]" eq "z80"} ? 12.0 : 5.0]
-		set overhead [expr $out_cycles / 3579545]
-		if {$start_time == -1} {
-			set start_time [expr [machine_info time] + $overhead]
-		} else {
-			set start_time [expr $start_time + $overhead]
-			incr ignored
-		}
-	}
-	
-	proc stop {} {
-		variable time
-		variable start_time
-		variable count
-		variable ignored
-		if {$start_time != -1} {
-			set time [expr [machine_info time] - $start_time + $time]
-			set start_time -1
-			incr count
-		} else {
-			incr ignored
-		}
-	}
-	
-	proc profile {} {
-		variable time
-		variable count
-		variable ignored
-		puts "Time: $time, count: $count, ignored: $ignored"
-	}
-	
-	namespace export profile
-}
-
-namespace import profile::*