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::*