Now loading and successfully relocating ProRWTS and PLASMA.

This commit is contained in:
Martin Haye 2017-01-04 09:17:13 -08:00
parent d9786058d8
commit 8ff169d1e6
11 changed files with 282 additions and 59 deletions

Binary file not shown.

View File

@ -113,9 +113,6 @@ INTERP = $03D0
LDA #$BF
STA PPH
STA IFPH
LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS)
TXS
LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX
RTS
PAGE0 = *

View File

@ -28,7 +28,8 @@
<include name="virtual/src/**/*.i"/>
<include name="virtual/src/**/*.ct"/>
<include name="virtual/data/disks/*.gz"/>
<include name="tools/PLASMA/src/PLVM02.SYSTEM.sys"/>
<include name="tools/PLASMA/src/PLVM02#4000"/>
<include name="tools/ProRWTS/PRORWTS2#4000"/>
</fileset>
</jar>
</target>

View File

@ -1205,6 +1205,14 @@ class A2PackPartitions
return wrapByteArray(arr)
}
def unwrapByteBuffer(buf) {
def len = buf.position()
def out = new byte[len]
buf.position(0)
buf.get(out)
return out
}
def readFont(name, path)
{
def num = fonts.size() + 1
@ -1231,7 +1239,7 @@ class A2PackPartitions
//def uncomp = new byte[inLen]
//lx47.decompress(outputData, 0, uncomp, 0, inLen)
//assert uncomp == inputData
// Verify the stream comes out right with overlapped decompression
def underlap = 2
def buf = new byte[inLen+underlap]
@ -1240,7 +1248,7 @@ class A2PackPartitions
lx47.decompress(buf, initialOffset, buf, 0, inLen)
def uncomp = Arrays.copyOfRange(buf, 0, inLen)
assert uncomp == inputData
uncompTotal += inLen
lx47Savings += savings
lz4Total += lz4Len
@ -1252,7 +1260,7 @@ class A2PackPartitions
println String.format("lz47 usize=%d savings=%d SKIP", inLen, savings)
}
}
// Transform the LZ4 format to something we call "LZ4M", where the small offsets are stored
// as one byte instead of two. In our data, that's about 1/3 of the offsets.
//
@ -1354,9 +1362,7 @@ class A2PackPartitions
{
// First, grab the uncompressed data into a byte array
def uncompressedLen = buf.position()
def uncompressedData = new byte[uncompressedLen]
buf.position(0)
buf.get(uncompressedData)
def uncompressedData = unwrapByteBuffer(buf)
// Now compress it with LZ4
assert uncompressedLen < 327678 : "data block too big"
@ -1369,7 +1375,7 @@ class A2PackPartitions
// Then recompress to LZ4M (pretty much always smaller)
def recompressedLen = recompress(compressedData, compressedLen, uncompressedData, uncompressedLen)
testLx47(uncompressedData, uncompressedLen, recompressedLen)
//testLx47(uncompressedData, uncompressedLen, recompressedLen)
// If we saved at least 20 bytes, take the compressed version.
if ((uncompressedLen - recompressedLen) >= 20) {
@ -1448,12 +1454,9 @@ class A2PackPartitions
hdrBuf.put((byte)(hdrEnd & 0xFF))
hdrBuf.put((byte)(hdrEnd >> 8))
hdrBuf.position(hdrEnd)
def hdrData = new byte[hdrEnd]
hdrBuf.position(0)
hdrBuf.get(hdrData)
// Finally, write out each chunk's data, including the header.
stream.write(hdrData)
stream.write(unwrapByteBuffer(hdrBuf))
chunks.each {
stream.write(it.buf.data, 0, it.buf.len)
}
@ -1467,6 +1470,7 @@ class A2PackPartitions
def prevUserDir = System.getProperty("user.dir")
def result
def errBuf = new ByteArrayOutputStream()
println "Nested: prog=$programName inDir=$inDir inDir=$inDir inFile=$inFile outFile=$outFile"
try
{
System.setProperty("user.dir", new File(inDir).getAbsolutePath())
@ -1620,18 +1624,50 @@ class A2PackPartitions
def assembleCore(inDir)
{
if (binaryStubsOnly)
return addToCache("sysCode", sysCode, "mem", 1, ByteBuffer.allocate(1))
return addToCache("sysCode", sysCode, "core", 1, ByteBuffer.allocate(1))
// Read in all the parts of the LegendOS core system and combine them together
// with block headers.
inDir = "build/" + inDir
def hash = getLastDep(new File(inDir, "mem.s"))
if (grabFromCache("sysCode", sysCode, "mem", hash))
return
println "Assembling mem.s"
new File(inDir + "build").mkdir()
String[] args = ["acme", "-o", "build/cmd.sys#2000", "mem.s"]
runNestedvm(acme.Acme.class, "ACME assembler", args, inDir, null, null)
addToCache("sysCode", sysCode, "mem", hash, readBinary(inDir + "build/cmd.sys#2000"))
new File(inDir + "build").mkdirs()
println "Created dir ${new File(inDir + "build")}"
def outBuf = ByteBuffer.allocate(50000)
def compressor = new Lx47Algorithm()
["loader", "decomp", "PRORWTS", "PLVM02", "mem"].each { name ->
def code
if (name == "PRORWTS")
code = readBinary(jitCopy(new File("build/tools/ProRWTS/PRORWTS2#4000")).toString())
else if (name == "PLVM02")
code = readBinary(jitCopy(new File("build/tools/PLASMA/src/PLVM02#4000")).toString())
else {
def hash = getLastDep(new File(inDir, "${name}.s"))
if (!grabFromCache("sysCode", sysCode, name, hash)) {
println "Assembling ${name}.s"
String[] args = ["acme", "-o", "build/$name", "${name}.s"]
runNestedvm(acme.Acme.class, "ACME assembler", args, inDir, null, null)
addToCache("sysCode", sysCode, name, hash, readBinary(inDir + "build/$name"))
}
code = sysCode[name].buf
}
println "Processing $name."
def compressed = (name ==~ /loader|decomp/) ?
code : wrapByteArray(compressor.compress(unwrapByteBuffer(code)))
if (name != "loader") {
// Uncompressed size first
outBuf.put((byte) (code.position() & 0xFF))
outBuf.put((byte) (code.position() >> 8))
// Then compressed size
outBuf.put((byte) (compressed.position() & 0xFF))
outBuf.put((byte) (compressed.position() >> 8))
}
compressed.flip()
outBuf.put(compressed)
}
// Write out the result
new File("build/src/core/build/LEGENDOS.SYSTEM.sys#2000").withOutputStream { stream ->
stream.write(unwrapByteBuffer(outBuf))
}
}
def compileModule(moduleName, codeDir, verbose = true)
@ -2699,11 +2735,9 @@ end
def createImage()
{
// Copy the PLASMA VM file to the output directory
copyIfNewer(jitCopy(new File("build/tools/PLASMA/src/PLVM02.SYSTEM.sys")), new File("build/root/PLVM02.SYSTEM.sys"))
// Copy the memory manager to the output directory
copyIfNewer(new File("build/src/core/build/cmd.sys#2000"), new File("build/root/cmd.sys#2000"))
// Copy the combined core executable to the output directory
copyIfNewer(new File("build/src/core/build/LEGENDOS.SYSTEM.sys#2000"),
new File("build/root/LEGENDOS.SYSTEM.sys#2000"))
// If we preserved a previous save game, copy it to the new image.
def prevSave = new File("build/prevGame/game.1.save.\$f1")

View File

@ -19,7 +19,7 @@ public class Lx47Algorithm
void addDebug(String format, Object... arguments) {
String str = String.format(format, arguments);
//System.out.println("Gen: " + str);
System.out.println("Gen: " + str);
debugs.add(str);
}
@ -275,10 +275,10 @@ public class Lx47Algorithm
int pos = input_index - optimal[input_index].lits + 1;
while (optimal[input_index].lits > 0) {
int n = Math.min(255, optimal[input_index].lits);
addDebug("lits l=%d", n);
addDebug("lits l=$%02x", n);
w.writeLiteralLen(n);
for (i = 0; i < n; i++, pos++) {
addDebug("lit $%x", input_data[pos]);
addDebug("lit $%02x", input_data[pos]);
w.writeByte(input_data[pos]);
}
optimal[input_index].lits -= n;
@ -289,12 +289,12 @@ public class Lx47Algorithm
// Sequence. If two in a row, insert a zero-length lit str
if (!prevIsLit) {
addDebug("lits l=0");
addDebug("lits l=$00");
w.writeBit(0);
}
// Now write sequence info
addDebug("seq l=%d o=%d", optimal[input_index].len, optimal[input_index].offset);
addDebug("seq l=$%02x o=$%04x", optimal[input_index].len, optimal[input_index].offset);
w.writeCodePair(optimal[input_index].len, optimal[input_index].offset);
prevIsLit = false;
}
@ -305,7 +305,7 @@ public class Lx47Algorithm
// EOF marker
if (!prevIsLit) {
addDebug("lits l=0");
addDebug("lits l=$00");
w.writeBit(0);
}
addDebug("EOF");
@ -393,10 +393,10 @@ public class Lx47Algorithm
// Check for literal string
while (true) {
len = r.readLiteralLen();
chkDebug("lits l=%d", len);
chkDebug("lits l=$%02x", len);
for (int i=0; i<len; i++) {
output_data[outPos++] = (byte) r.readByte();
chkDebug("lit $%x", output_data[outPos-1]);
chkDebug("lit $%02x", output_data[outPos-1]);
}
if (len != 255)
break;
@ -410,7 +410,7 @@ public class Lx47Algorithm
int codePair = r.readCodePair();
len = codePair & 0xFFFF;
int off = codePair >> 16;
chkDebug("seq l=%d o=%d", len, off);
chkDebug("seq l=$%02x o=$%04x", len, off);
while (len-- > 0) {
output_data[outPos] = output_data[outPos - off];
++outPos;

View File

@ -1,5 +1,5 @@
.SUFFIXES =
PRORWTS = PRORWTS2\#800
PRORWTS = PRORWTS2\#4000
all: $(PRORWTS)

Binary file not shown.

View File

@ -3,7 +3,7 @@
;license:BSD-3-Clause
!cpu 6502
*=$800
*=$4000
;place no code before init label below.
@ -28,7 +28,7 @@
;i.e. running from main if accessing main, running from aux if accessing aux
bounds_check = 0 ;set to 1 to prevent access beyond the end of the file
;but limits file size to 64k-2 bytes.
load_high = 1 ;set to 1 to load to top of RAM (either main or banked, enables a himem check)
load_high = 0 ;set to 1 to load to top of RAM (either main or banked, enables a himem check)
load_banked = 1 ;set to 1 to load into banked RAM instead of main RAM
lc_bank = 1 ;load into specified bank (1 or 2) if load_banked=1
@ -40,7 +40,7 @@
reloc = $fb00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch
} ;PASS2
} else { ;load_high
reloc = $d000 ;page-aligned, but otherwise wherever you want
reloc = $ef00 ;page-aligned, but otherwise wherever you want
} ;load_high
} else { ;load_banked
!if load_high = 1 {

View File

@ -9,18 +9,10 @@
;****************************************************************************************
;@com.wudsn.ide.asm.hardware=APPLE2
; Memory manager
; Lx47 Decompressor
; ------------------
;
; See detailed description in mem.i
* = $2000 ; PLASMA loader loads us initially at $2000
; Use hi-bit ASCII for Apple II
!convtab "../include/hiBitAscii.ct"
; Global definitions
!source "../include/global.i"
* = $DF00
tmp = $2 ; len 2
pTmp = $4 ; len 2
@ -30,6 +22,13 @@ pSrc = $C ; len 2
pDst = $E ; len 2
pEnd = $10 ; len 2
cout = $FDED
prbyte = $FDDA
crout = $FD8E
rdkey = $FD0C
DEBUG = 0
; Decompress from pSrc to pDst, stop at pEnd. The source and dest can overlap, as long as the
; source block ends (at least) 2 bytes beyond the end of the dest block, e.g.
; DDDDDDDDDDDDDDD
@ -43,8 +42,9 @@ decomp !zone {
.lits asl bits ; get bit that tells us whether there's a literal string
bne + ; ran out of bits in bit buffer?
.lits2 jsr .getbts ; get more bits
+ bcc .seq ; if bit was zero, no literals: go straight to sequence
+ bcc .endchk ; if bit was zero, no literals: go straight to sequence (after end check)
jsr .gamma ; Yes we have literals. Get the count.
!if DEBUG { jsr .dbg1 }
tax
cpx #255 ; special case: long literal marked by len=255; chk and save to carry
- lda (pSrc),y
@ -62,7 +62,8 @@ decomp !zone {
cmp pEnd
lda pDst+1
sbc pEnd+1
bcs .ret
;bcs .ret
bcs .chk
.seq lda (pSrc),y
inc pSrc
@ -79,9 +80,9 @@ decomp !zone {
sta tmp
jsr .gamma
lsr
rol tmp
ror tmp
lsr
rol tmp
ror tmp
sta tmp+1
.gotoff lda pDst
clc ; effectively add 1 to offset.
@ -97,6 +98,7 @@ decomp !zone {
adc #1 ; A>=1 + sec + 1 => final len 3 or more
tax
.gotlen
!if DEBUG { jsr .dbg2 }
- lda (pTmp),y
sta (pDst),y
iny
@ -109,7 +111,7 @@ decomp !zone {
ldy #0 ; back to 0 as expected by lits section
bcc .lits
inc pDst+1
bcs .lits ; always taken
jmp .lits
; Read an Elias Gamma value into A. Destroys X. Sets carry.
.gamma lda #1
@ -134,4 +136,42 @@ decomp !zone {
sta bits
txa
.ret rts
.chk ora pDst
eor pEnd
beq .ret
brk
!if DEBUG {
.dbg1 pha
lda #'L'|$80
jsr cout
pla
pha
.dbgEnd jsr prbyte
jsr crout
;- bit $C000
; bpl -
; bit $C010
pla
rts
.dbg2 pha
lda #'S'|$80
jsr cout
txa
jsr prbyte
lda #' '|$80
jsr cout
lda tmp
clc
adc #1
pha
lda tmp+1
adc #0
jsr prbyte
pla
jmp .dbgEnd
}
} ; end of zone

View File

@ -0,0 +1,151 @@
;****************************************************************************************
; Copyright (C) 2017 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
; (the "License"); you may not use this file except in compliance with the License.
; You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
; Unless required by applicable law or agreed to in writing, software distributed under
; the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
; ANY KIND, either express or implied. See the License for the specific language
; governing permissions and limitations under the License.
;****************************************************************************************
;@com.wudsn.ide.asm.hardware=APPLE2
; LegendOS bootstrapping loader
; -----------------------------
; Use hi-bit ASCII for Apple II
!convtab "../include/hiBitAscii.ct"
; Handy global defs
!source "../include/global.i"
DEBUG = 0
* = $2000
tmp = $2 ; len 2
pTmp = $4 ; len 2
bits = $6 ; len 1
pSrc = $C ; len 2
pDst = $E ; len 2
pEnd = $10 ; len 2
pData = $80 ; len 2
pRun = $82 ; len 2
decomp = $DF00
init ; Init pointer to blocks we're going to move/decompress
lda #<dataStart
sta pData
lda #>dataStart
sta pData+1
; temporary: copy ROM so we can debug decompressor
bit setLcWr ; read from ROM, write to LC ram
bit setLcWr
ldy #0
sty pSrc
ldx #$f8
-- stx pSrc+1
- lda (pSrc),y
sta (pSrc),y
iny
bne -
inx
bne --
; First is the decompressor itself (special: just copy one page)
jsr getBlk
bit setLcRW+lcBank1 ; switch in target bank
bit setLcRW+lcBank1
- lda (pSrc),y
.st sta decomp,y
iny
bne -
; Next comes ProRWTS
jsr runBlk
; Then PLASMA
jsr runBlk
; And finally the memory mgr (fall through)
runBlk jsr getBlk ; get block size and calc pointers
!if DEBUG {
lda #1 ; turn on printer
jsr $FE95
jsr debug
}
bit setLcRW+lcBank1
jsr decomp ; decompress the code
!if DEBUG {
lda #"R"
jsr ROM_cout
jsr ROM_crout
}
jmp $4000 ; and run it so it'll relocate itself
getByte ldy #0
lda (pData),y
inc pData
bne +
inc pData+1
+ rts
getWord jsr getByte
pha
jsr getByte
tax
pla
clc
rts
getBlk ; Get uncompressed len from the block header,
; and calculate dest end (based on start of $4000)
jsr getWord
sta pEnd
txa
adc #$40
sta pEnd+1
; Get compressed len
jsr getWord
pha ; save lo byte of len
; We're now looking at start of compressed data. Record that pointer.
lda pData
sta pSrc
lda pData+1
sta pSrc+1
; We always decompress to $4000
sty pDst ; Y already zero
lda #$40
sta pDst+1
; Add compressed length to get to start of next block
pla ; get len back
adc pData
sta pData
txa
adc pData+1
sta pData+1
rts
!if DEBUG {
debug jsr ROM_crout
lda #"B"
jsr ROM_cout
lda pSrc+1
ldx pSrc
jsr .pr
lda pDst+1
ldx pDst
jsr .pr
lda pEnd+1
ldx pEnd
jsr ROM_prntax
jmp ROM_crout
.pr jsr ROM_prntax
lda #" "
jmp ROM_cout
}
dataStart = *

View File

@ -14,7 +14,7 @@
;
; See detailed description in mem.i
* = $2000 ; PLASMA loader loads us initially at $2000
* = $4000 ; PLASMA loader loads us initially at $2000
; Use hi-bit ASCII for Apple II
!convtab "../include/hiBitAscii.ct"