goblin+jareth console HW scrolling, cleanup
This commit is contained in:
@@ -133,8 +133,8 @@ static void goblin_reset(struct goblin_softc *);
|
||||
static int init_programs(struct goblin_softc *sc);
|
||||
static int power_on(struct goblin_softc *sc);
|
||||
static int power_off(struct goblin_softc *sc);
|
||||
static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n);
|
||||
static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n);
|
||||
static int jareth_scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n);
|
||||
static int jareth_fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n);
|
||||
static const uint32_t program_scroll128[12] = { 0x407c0012,0x00140080,0x201c0013,0x60fc7013,0x00170146,0xfe000148,0x000e10c6,0x010000c9,0x00004005,0xfb000809,0x0000000a,0x0000000a };
|
||||
static const uint32_t program_fill128[12] = { 0x407c0012,0x00140080,0x607c1013,0x00170146,0xfe800148,0x000e10c6,0x010000c9,0x00004005,0xfb800809,0x0000000a,0x0000000a,0x0000000a };
|
||||
|
||||
@@ -361,13 +361,13 @@ goblinioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
|
||||
|
||||
case GOBLIN_SCROLL: {
|
||||
struct scrolltest *st = (struct scrolltest *)data;
|
||||
scroll(sc, st->y0, st->y1, st->x0, st->w, st->n);
|
||||
jareth_scroll(sc, st->y0, st->y1, st->x0, st->w, st->n);
|
||||
}
|
||||
break;
|
||||
|
||||
case GOBLIN_FILL: {
|
||||
struct scrolltest *st = (struct scrolltest *)data;
|
||||
fill(sc, st->y0, st->y1, st->x0, st->w, st->n);
|
||||
jareth_fill(sc, st->y0, st->y1, st->x0, st->w, st->n);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -726,32 +726,39 @@ goblin_reset(struct goblin_softc *sc)
|
||||
#define REG_BASE(reg) (base + (reg * 32))
|
||||
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
|
||||
|
||||
static int start_job(struct goblin_softc *sc);
|
||||
static int wait_job(struct goblin_softc *sc, uint32_t param);
|
||||
static int start_job(struct goblin_softc *sc, int verbose);
|
||||
static int wait_job(struct goblin_softc *sc, uint32_t param, int verbose);
|
||||
|
||||
static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n) {
|
||||
static int jareth_scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n) {
|
||||
const uint32_t base = 0;
|
||||
const int pidx = 0;
|
||||
int i;
|
||||
|
||||
power_on(sc);
|
||||
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,1), (0x8f800000 + y1 * sc->sc_stride + x0));
|
||||
if (y0 > y1) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0)); /* fixme: replace 0x8f800000 by a prom attributes */
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,1), (0x8f800000 + y1 * sc->sc_stride + x0));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (sc->sc_stride));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,1), (sc->sc_stride));
|
||||
} else {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0 + (n-1) * sc->sc_stride)); /* fixme: replace 0x8f800000 by a prom attributes */
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,1), (0x8f800000 + y1 * sc->sc_stride + x0 + (n-1) * sc->sc_stride));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (-sc->sc_stride));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,1), (-sc->sc_stride));
|
||||
}
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,0), (w));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,0), (n));
|
||||
for (i = 1 ; i < 8 ; i++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,i), 0);
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,i), 0);
|
||||
}
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (sc->sc_stride));
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,1), (sc->sc_stride));
|
||||
jareth_mpstart_write(sc, program_offset[pidx]);
|
||||
jareth_mplen_write(sc, program_len[pidx]);
|
||||
|
||||
(void)start_job(sc);
|
||||
(void)start_job(sc, 0);
|
||||
delay(1);
|
||||
(void)wait_job(sc, 2);
|
||||
(void)wait_job(sc, 2, 0);
|
||||
|
||||
power_off(sc);
|
||||
|
||||
@@ -759,7 +766,7 @@ static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n)
|
||||
}
|
||||
|
||||
|
||||
static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n) {
|
||||
static int jareth_fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n) {
|
||||
const uint32_t base = 0;
|
||||
const int pidx = 1;
|
||||
int i;
|
||||
@@ -780,9 +787,9 @@ static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n)
|
||||
jareth_mpstart_write(sc, program_offset[pidx]);
|
||||
jareth_mplen_write(sc, program_len[pidx]);
|
||||
|
||||
(void)start_job(sc);
|
||||
(void)start_job(sc, 0);
|
||||
delay(1);
|
||||
(void)wait_job(sc, 1);
|
||||
(void)wait_job(sc, 1, 0);
|
||||
|
||||
power_off(sc);
|
||||
|
||||
@@ -827,7 +834,7 @@ jareth_copyrows(void *cookie, int src, int dst, int n)
|
||||
/* int x3 = ri->ri_xorigin + ri->ri_emuwidth - 1; */
|
||||
/* int y3 = ri->ri_yorigin + dst + n - 1; */
|
||||
|
||||
scroll(sc, y0, y2, x0, ri->ri_emuwidth, n);
|
||||
jareth_scroll(sc, y0, y2, x0, ri->ri_emuwidth, n);
|
||||
|
||||
#if 0
|
||||
if (y0 > y2) {
|
||||
@@ -852,10 +859,11 @@ jareth_copyrows(void *cookie, int src, int dst, int n)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int start_job(struct goblin_softc *sc) {
|
||||
static int start_job(struct goblin_softc *sc, int verbose) {
|
||||
uint32_t status = jareth_status_read(sc);
|
||||
if (status & (1<<CSR_JARETH_STATUS_RUNNING_OFFSET)) {
|
||||
aprint_error_dev(sc->sc_dev, "START - Jareth status: 0x%08x, still running?\n", status);
|
||||
if (verbose)
|
||||
aprint_error_dev(sc->sc_dev, "START - Jareth status: 0x%08x, still running?\n", status);
|
||||
return ENXIO;
|
||||
}
|
||||
jareth_control_write(sc, 1);
|
||||
@@ -864,10 +872,10 @@ static int start_job(struct goblin_softc *sc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_job(struct goblin_softc *sc, uint32_t param) {
|
||||
static int wait_job(struct goblin_softc *sc, uint32_t param, int verbose) {
|
||||
uint32_t status = jareth_status_read(sc);
|
||||
int count = 0;
|
||||
int max_count = 2000;
|
||||
int max_count = 3000;
|
||||
int del = 1;
|
||||
const int max_del = 64;
|
||||
static int max_del_seen = 1;
|
||||
@@ -883,23 +891,27 @@ static int wait_job(struct goblin_softc *sc, uint32_t param) {
|
||||
}
|
||||
if (del > max_del_seen) {
|
||||
max_del_seen = del;
|
||||
aprint_normal_dev(sc->sc_dev, "WAIT - new max delay %d after %d count (param was %u)\n", max_del_seen, count, param);
|
||||
if (verbose)
|
||||
aprint_normal_dev(sc->sc_dev, "WAIT - new max delay %d after %d count (param was %u)\n", max_del_seen, count, param);
|
||||
}
|
||||
if (count > max_cnt_seen) {
|
||||
max_cnt_seen = count;
|
||||
aprint_normal_dev(sc->sc_dev, "WAIT - new max count %d with %d delay (param was %u)\n", max_cnt_seen, del, param);
|
||||
|
||||
if (verbose)
|
||||
aprint_normal_dev(sc->sc_dev, "WAIT - new max count %d with %d delay (param was %u)\n", max_cnt_seen, del, param);
|
||||
}
|
||||
|
||||
//jareth_control_write(sc, 0);
|
||||
if (status & (1<<CSR_JARETH_STATUS_RUNNING_OFFSET)) {
|
||||
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x (pc 0x%08x), did not finish in time? [inst: 0x%08x ls_status: 0x%08x]\n", status, (status>>1)&0x03ff, jareth_instruction_read(sc), jareth_ls_status_read(sc));
|
||||
if (verbose)
|
||||
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x (pc 0x%08x), did not finish in time? [inst: 0x%08x ls_status: 0x%08x]\n", status, (status>>1)&0x03ff, jareth_instruction_read(sc), jareth_ls_status_read(sc));
|
||||
return ENXIO;
|
||||
} else if (status & (1<<CSR_JARETH_STATUS_SIGILL_OFFSET)) {
|
||||
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x, sigill [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc));
|
||||
if (verbose)
|
||||
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x, sigill [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc));
|
||||
return ENXIO;
|
||||
} else if (status & (1<<CSR_JARETH_STATUS_ABORT_OFFSET)) {
|
||||
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x, aborted [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc));
|
||||
if (verbose)
|
||||
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x, aborted [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc));
|
||||
return ENXIO;
|
||||
} else {
|
||||
//aprint_normal_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x [%d] ls_status: 0x%08x\n", status, count, jareth_ls_status_read(sc));
|
||||
|
||||
@@ -10,19 +10,17 @@ prime_string = "$2^{{255}}-19$" # 2\ :sup:`255`-19
|
||||
field_latex = "$\mathbf{{F}}_{{{{2^{{255}}}}-19}}$"
|
||||
|
||||
opcode_bits = 5 # number of bits used to encode the opcode field
|
||||
opcodes = { # mnemonic : [bit coding, docstring] ; if bit 6 (0x20) is set, shift a
|
||||
opcodes = { # mnemonic : [bit coding, docstring] ; if bit 6 (0x20) is set, shift a/b/q (star)
|
||||
"UDF" : [-1, "Placeholder for undefined opcodes"],
|
||||
"PSA" : [0, "Wd $\gets$ Ra // pass A"],
|
||||
"PSB" : [1, "Wd $\gets$ Rb // pass B"],
|
||||
"PSB" : [1, "Wd $\gets$ Rb // pass B"], # for star version mostly
|
||||
# 2 MSK
|
||||
"XOR" : [3, "Wd $\gets$ Ra ^ Rb // bitwise XOR"],
|
||||
"NOT" : [4, "Wd $\gets$ ~Ra // binary invert"],
|
||||
"ADD32" : [5, "Wd[x..x+32] $\gets$ Ra[x..x+32] + Rb[x..x+32] // vector 32-bit binary add"],
|
||||
"SUB32" : [6, "Wd[x..x+32] $\gets$ Ra[x..x+32] - Rb[x..x+32] // vector 32-bit binary add"],
|
||||
#"ADD" : [5, "Wd $\gets$ Ra + Rb // 256-bit binary add"],
|
||||
#"SUB" : [6, "Wd $\gets$ Ra - Rb // 256-bit binary subtraction"],
|
||||
"ADD32V" : [5, "Wd[x..x+32] $\gets$ Ra[x..x+32] + Rb[x..x+32] // vector 32-bit binary add"],
|
||||
"SUB32V" : [6, "Wd[x..x+32] $\gets$ Ra[x..x+32] - Rb[x..x+32] // vector 32-bit binary add"],
|
||||
"AND" : [7, "Wd $\gets$ Ra & Rb // bitwise AND"], # replace MUL
|
||||
"BRNZ" : [8, "If Ra != 0 then mpc[9:0] $\gets$ mpc[9:0] + immediate[9:0] + 1, else mpc $\gets$ mpc + 1 // Branch if non-zero"], # replace TRD
|
||||
"BRNZ32" : [8, "If Ra[0:32] != 0 then mpc[9:0] $\gets$ mpc[9:0] + immediate[9:0] + 1, else mpc $\gets$ mpc + 1 // Branch if non-zero"], # replace TRD
|
||||
"BRZ" : [9, "If Ra == 0 then mpc[9:0] $\gets$ mpc[9:0] + immediate[9:0] + 1, else mpc $\gets$ mpc + 1 // Branch if zero"],
|
||||
"FIN" : [10, "halt execution and assert interrupt to host CPU that microcode execution is done"],
|
||||
"SHL" : [11, "Wd $\gets$ Ra << 1 // shift Ra left by one and store in Wd"],
|
||||
@@ -331,7 +329,7 @@ passthrough.
|
||||
|
||||
class ExecAddSub(ExecUnit, AutoDoc):
|
||||
def __init__(self, width=256):
|
||||
ExecUnit.__init__(self, width, ["ADD32", "SUB32"])
|
||||
ExecUnit.__init__(self, width, ["ADD32V", "SUB32V"])
|
||||
self.notes = ModuleDoc(title="Add/Sub ExecUnit Subclass", body=f"""
|
||||
""")
|
||||
|
||||
@@ -340,9 +338,9 @@ class ExecAddSub(ExecUnit, AutoDoc):
|
||||
self.instruction_out.eq(self.instruction_in),
|
||||
]
|
||||
self.comb += [
|
||||
If(self.instruction.opcode == opcodes["ADD32"][0],
|
||||
If(self.instruction.opcode == opcodes["ADD32V"][0],
|
||||
[ self.q[x*32:(x+1)*32].eq(self.a[x*32:(x+1)*32] + self.b[x*32:(x+1)*32]) for x in range(0, width//32) ],
|
||||
).Elif(self.instruction.opcode == opcodes["SUB32"][0],
|
||||
).Elif(self.instruction.opcode == opcodes["SUB32V"][0],
|
||||
[ self.q[x*32:(x+1)*32].eq(self.a[x*32:(x+1)*32] - self.b[x*32:(x+1)*32]) for x in range(0, width//32) ],
|
||||
),
|
||||
]
|
||||
@@ -1057,8 +1055,8 @@ Here are the currently implemented opcodes for The Engine:
|
||||
seq.act("EXEC", # not a great name. This is actually where the register file fetches its contents.
|
||||
If(instruction.opcode == opcodes["BRZ"][0],
|
||||
NextState("DO_BRZ"),
|
||||
).Elif(instruction.opcode == opcodes["BRNZ"][0],
|
||||
NextState("DO_BRNZ"),
|
||||
).Elif(instruction.opcode == opcodes["BRNZ32"][0],
|
||||
NextState("DO_BRNZ32"),
|
||||
).Elif(instruction.opcode == opcodes["FIN"][0],
|
||||
NextState("IDLE"),
|
||||
NextValue(running, 0),
|
||||
@@ -1107,8 +1105,8 @@ Here are the currently implemented opcodes for The Engine:
|
||||
)
|
||||
),
|
||||
)
|
||||
seq.act("DO_BRNZ",
|
||||
If(ra_dat != 0,
|
||||
seq.act("DO_BRNZ32",
|
||||
If(ra_dat[0:32] != 0,
|
||||
If( (sext_immediate + mpc + 1 < mpc_stop) & (sext_immediate + mpc + 1 >= self.mpstart.fields.mpstart), # validate new PC is in range
|
||||
NextState("FETCH"),
|
||||
NextValue(mpc, sext_immediate + mpc + 1),
|
||||
|
||||
@@ -25,7 +25,7 @@ fn main() -> std::io::Result<()> {
|
||||
// slow
|
||||
setmq %31, %1, #16
|
||||
and %5, %2, #15
|
||||
sub32 %6, %2, %5
|
||||
sub32v %6, %2, %5
|
||||
brz done, %6
|
||||
loop:
|
||||
psa %18, %16
|
||||
@@ -33,7 +33,7 @@ fn main() -> std::io::Result<()> {
|
||||
psa* %17, %16
|
||||
psa %20, %17
|
||||
store128inc %31, %2, %17
|
||||
sub32 %6, %6, #16
|
||||
sub32v %6, %6, #16
|
||||
brz last, %6
|
||||
loadh128inc %16, %0, %16
|
||||
loadh128inc %17, %1, %17
|
||||
@@ -72,16 +72,16 @@ fn main() -> std::io::Result<()> {
|
||||
// store to DST w/ post-increment
|
||||
store256inc %31, %1, %7
|
||||
// sub 32 (#5 is 32...) from live X count
|
||||
sub32 %5, %5, #5
|
||||
sub32v %5, %5, #5
|
||||
// if X count is not 0, keep looping
|
||||
brnz loop_x, %5
|
||||
brnz32 loop_x, %5
|
||||
|
||||
// decrement Y count
|
||||
sub32 %3, %3, #1
|
||||
sub32v %3, %3, #1
|
||||
// if 0, finished
|
||||
brz done, %3
|
||||
// add strides to initial addresses
|
||||
add32 %0, %0, %4
|
||||
add32v %0, %0, %4
|
||||
// loop to do next line
|
||||
brz loop_y, #0
|
||||
done:
|
||||
@@ -112,16 +112,16 @@ fn main() -> std::io::Result<()> {
|
||||
// store to DST w/ post-increment
|
||||
store128inc %31, %1, %7
|
||||
// sub 16 (#16 is 16) from live X count
|
||||
sub32 %5, %5, #16
|
||||
sub32v %5, %5, #16
|
||||
// if X count is not 0, keep looping
|
||||
brnz loop_x, %5
|
||||
brnz32 loop_x, %5
|
||||
|
||||
// decrement Y count
|
||||
sub32 %3, %3, #1
|
||||
sub32v %3, %3, #1
|
||||
// if 0, finished
|
||||
brz done, %3
|
||||
// add strides to initial addresses
|
||||
add32 %0, %0, %4
|
||||
add32v %0, %0, %4
|
||||
// loop to do next line
|
||||
brz loop_y, #0
|
||||
done:
|
||||
@@ -151,16 +151,16 @@ fn main() -> std::io::Result<()> {
|
||||
// store to DST w/ post-increment
|
||||
store128inc %31, %0, %1
|
||||
// sub 16 (#16 is 16) from live X count
|
||||
sub32 %5, %5, #16
|
||||
sub32v %5, %5, #16
|
||||
// if X count is not 0, keep looping
|
||||
brnz loop_x, %5
|
||||
brnz32 loop_x, %5
|
||||
|
||||
// decrement Y count
|
||||
sub32 %3, %3, #1
|
||||
sub32v %3, %3, #1
|
||||
// if 0, finished
|
||||
brz done, %3
|
||||
// add strides to initial addresses
|
||||
add32 %0, %0, %4
|
||||
add32v %0, %0, %4
|
||||
// loop to do next line
|
||||
brz loop_y, #0
|
||||
done:
|
||||
|
||||
Reference in New Issue
Block a user