OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/trunk
    from Rev 15 to Rev 16
    Reverse comparison

Rev 15 → Rev 16

/monitor/monitor-digilent/mmu.c
0,0 → 1,104
/*
* mmu.c -- memory and TLB access
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "mmu.h"
#include "start.h"
 
 
static Word tlbIndex;
static Word tlbEntryHi;
static Word tlbEntryLo;
 
 
Word mmuReadWord(Word vAddr) {
return *(Word *)vAddr;
}
 
 
Half mmuReadHalf(Word vAddr) {
return *(Half *)vAddr;
}
 
 
Byte mmuReadByte(Word vAddr) {
return *(Byte *)vAddr;
}
 
 
void mmuWriteWord(Word vAddr, Word data) {
*(Word *)vAddr = data;
}
 
 
void mmuWriteHalf(Word vAddr, Half data) {
*(Half *)vAddr = data;
}
 
 
void mmuWriteByte(Word vAddr, Byte data) {
*(Byte *)vAddr = data;
}
 
 
Word mmuGetIndex(void) {
return tlbIndex;
}
 
 
void mmuSetIndex(Word value) {
tlbIndex = value;
}
 
 
Word mmuGetEntryHi(void) {
return tlbEntryHi;
}
 
 
void mmuSetEntryHi(Word value) {
tlbEntryHi = value;
}
 
 
Word mmuGetEntryLo(void) {
return tlbEntryLo;
}
 
 
void mmuSetEntryLo(Word value) {
tlbEntryLo = value;
}
 
 
TLB_Entry mmuGetTLB(int index) {
Word hi;
Word lo;
TLB_Entry result;
 
hi = getTLB_HI(index);
lo = getTLB_LO(index);
result.page = hi & PAGE_MASK;
result.frame = lo & PAGE_MASK;
result.write = (lo & TLB_WRITE) ? true : false;
result.valid = (lo & TLB_VALID) ? true : false;
return result;
}
 
 
void mmuSetTLB(int index, TLB_Entry tlbEntry) {
Word flags;
 
flags = 0;
if (tlbEntry.write) {
flags |= TLB_WRITE;
}
if (tlbEntry.valid) {
flags |= TLB_VALID;
}
setTLB(index, tlbEntry.page, tlbEntry.frame | flags);
}
/monitor/monitor-digilent/instr.c
0,0 → 1,115
/*
* instr.c -- instruction encoding
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "instr.h"
 
 
/*
* This is the ECO32 machine instruction set.
* The table below needs no particular order
* and may have gaps in the instruction encoding.
*/
Instr instrTbl[] = {
{ "add", FORMAT_RRY, OP_ADD },
{ "sub", FORMAT_RRY, OP_SUB },
{ "mul", FORMAT_RRY, OP_MUL },
{ "mulu", FORMAT_RRX, OP_MULU },
{ "div", FORMAT_RRY, OP_DIV },
{ "divu", FORMAT_RRX, OP_DIVU },
{ "rem", FORMAT_RRY, OP_REM },
{ "remu", FORMAT_RRX, OP_REMU },
{ "and", FORMAT_RRX, OP_AND },
{ "or", FORMAT_RRX, OP_OR },
{ "xor", FORMAT_RRX, OP_XOR },
{ "xnor", FORMAT_RRX, OP_XNOR },
{ "sll", FORMAT_RRX, OP_SLL },
{ "slr", FORMAT_RRX, OP_SLR },
{ "sar", FORMAT_RRX, OP_SAR },
{ "ldhi", FORMAT_RHH, OP_LDHI },
{ "beq", FORMAT_RRB, OP_BEQ },
{ "bne", FORMAT_RRB, OP_BNE },
{ "ble", FORMAT_RRB, OP_BLE },
{ "bleu", FORMAT_RRB, OP_BLEU },
{ "blt", FORMAT_RRB, OP_BLT },
{ "bltu", FORMAT_RRB, OP_BLTU },
{ "bge", FORMAT_RRB, OP_BGE },
{ "bgeu", FORMAT_RRB, OP_BGEU },
{ "bgt", FORMAT_RRB, OP_BGT },
{ "bgtu", FORMAT_RRB, OP_BGTU },
{ "j", FORMAT_J, OP_J },
{ "jr", FORMAT_JR, OP_JR },
{ "jal", FORMAT_J, OP_JAL },
{ "jalr", FORMAT_JR, OP_JALR },
{ "trap", FORMAT_N, OP_TRAP },
{ "rfx", FORMAT_N, OP_RFX },
{ "ldw", FORMAT_RRS, OP_LDW },
{ "ldh", FORMAT_RRS, OP_LDH },
{ "ldhu", FORMAT_RRS, OP_LDHU },
{ "ldb", FORMAT_RRS, OP_LDB },
{ "ldbu", FORMAT_RRS, OP_LDBU },
{ "stw", FORMAT_RRS, OP_STW },
{ "sth", FORMAT_RRS, OP_STH },
{ "stb", FORMAT_RRS, OP_STB },
{ "mvfs", FORMAT_RH, OP_MVFS },
{ "mvts", FORMAT_RH, OP_MVTS },
{ "tbs", FORMAT_N, OP_TBS },
{ "tbwr", FORMAT_N, OP_TBWR },
{ "tbri", FORMAT_N, OP_TBRI },
{ "tbwi", FORMAT_N, OP_TBWI }
};
 
 
Instr *instrCodeTbl[64];
 
 
static int instrCompare(const void *instr1, const void *instr2) {
return strcmp(((Instr *) instr1)->name, ((Instr *) instr2)->name);
}
 
 
void initInstrTable(void) {
int i;
 
/* first sort instruction table alphabetically */
qsort(instrTbl, sizeof(instrTbl)/sizeof(instrTbl[0]),
sizeof(instrTbl[0]), instrCompare);
/* then initialize instruction code table */
for (i = 0; i < 64; i++) {
instrCodeTbl[i] = NULL;
}
for (i = 0; i < sizeof(instrTbl)/sizeof(instrTbl[0]); i++) {
instrCodeTbl[instrTbl[i].opcode] = &instrTbl[i];
if (instrTbl[i].format == FORMAT_RRX ||
instrTbl[i].format == FORMAT_RRY) {
/* enter the immediate variant of this instruction also */
instrCodeTbl[instrTbl[i].opcode + 1] = &instrTbl[i];
}
}
}
 
 
Instr *lookupInstr(char *name) {
int lo, hi, tst;
int res;
 
lo = 0;
hi = sizeof(instrTbl) / sizeof(instrTbl[0]) - 1;
while (lo <= hi) {
tst = (lo + hi) / 2;
res = strcmp(instrTbl[tst].name, name);
if (res == 0) {
return &instrTbl[tst];
}
if (res < 0) {
lo = tst + 1;
} else {
hi = tst - 1;
}
}
return NULL;
}
/monitor/monitor-digilent/start.h
0,0 → 1,57
/*
* start.h -- ECO32 ROM monitor startup and support routines
*/
 
 
#ifndef _START_H_
#define _START_H_
 
 
typedef struct {
Word reg[32]; /* general purpose registers */
Word psw; /* PSW */
Word tlbIndex; /* TLB index register */
Word tlbHi; /* TLB EntryHi register */
Word tlbLo; /* TLB EntryLo register */
} UserContext;
 
typedef struct {
Word r31; /* return address */
Word r29; /* stack pointer */
Word r16; /* local variable */
Word r17; /* local variable */
Word r18; /* local variable */
Word r19; /* local variable */
Word r20; /* local variable */
Word r21; /* local variable */
Word r22; /* local variable */
Word r23; /* local variable */
} MonitorState;
 
 
int cinchk(void);
int cin(void);
int coutchk(void);
void cout(char c);
 
int sinchk(void);
int sin(void);
int soutchk(void);
void sout(char c);
 
int dskcap(int dskno);
int dskio(int dskno, char cmd, int sct, Word addr, int nscts);
 
Word getTLB_HI(int index);
Word getTLB_LO(int index);
void setTLB(int index, Word entryHi, Word entryLo);
 
Bool saveState(MonitorState *msp);
 
extern MonitorState *monitorReturn;
extern UserContext userContext;
 
void resume(void);
 
 
#endif /* _START_H_ */
/monitor/monitor-digilent/mmu.h
0,0 → 1,45
/*
* mmu.h -- memory and TLB access
*/
 
 
#ifndef _MMU_H_
#define _MMU_H_
 
 
#define TLB_SHFT 5 /* log2 of number of TLB entries */
#define TLB_SIZE (1 << TLB_SHFT) /* total number of TLB entries */
#define TLB_MASK (TLB_SIZE - 1) /* mask for number of TLB entries */
#define TLB_FIXED 4 /* number of fixed TLB entries */
 
#define TLB_WRITE (1 << 1) /* write bit in EntryLo */
#define TLB_VALID (1 << 0) /* valid bit in EntryLo */
 
 
typedef struct {
Word page; /* 20 high-order bits of virtual address */
Word frame; /* 20 high-order bits of physical address */
Bool write; /* must be true to allow writing to the page */
Bool valid; /* must be true for the entry to be valid */
} TLB_Entry;
 
 
Word mmuReadWord(Word vAddr);
Half mmuReadHalf(Word vAddr);
Byte mmuReadByte(Word vAddr);
void mmuWriteWord(Word vAddr, Word data);
void mmuWriteHalf(Word vAddr, Half data);
void mmuWriteByte(Word vAddr, Byte data);
 
Word mmuGetIndex(void);
void mmuSetIndex(Word value);
Word mmuGetEntryHi(void);
void mmuSetEntryHi(Word value);
Word mmuGetEntryLo(void);
void mmuSetEntryLo(Word Value);
 
TLB_Entry mmuGetTLB(int index);
void mmuSetTLB(int index, TLB_Entry tlbEntry);
 
 
#endif /* _MMU_H_ */
/monitor/monitor-digilent/instr.h
0,0 → 1,125
/*
* instr.h -- instruction encoding
*/
 
 
#ifndef _INSTR_H_
#define _INSTR_H_
 
 
#define FORMAT_N 0 /* no operands */
#define FORMAT_RH 1 /* one register and a half operand */
#define FORMAT_RHH 2 /* one register and a half operand */
/* ATTENTION: high-order 16 bits encoded */
#define FORMAT_RRH 3 /* two registers and a half operand */
#define FORMAT_RRS 4 /* two registers and a signed half operand */
#define FORMAT_RRR 5 /* three register operands */
#define FORMAT_RRX 6 /* either FORMAT_RRR or FORMAT_RRH */
#define FORMAT_RRY 7 /* either FORMAT_RRR or FORMAT_RRS */
#define FORMAT_RRB 8 /* two registers and a 16 bit signed
offset operand */
#define FORMAT_J 9 /* no registers and a 26 bit signed
offset operand */
#define FORMAT_JR 10 /* one register operand */
 
 
#define MASK(n) ((((Word) 1) << n) - 1)
#define SIGN(n) (((Word) 1) << (n - 1))
#define ZEXT16(x) (((Word) (x)) & MASK(16))
#define SEXT16(x) (((Word) (x)) & SIGN(16) ? \
(((Word) (x)) | ~MASK(16)) : \
(((Word) (x)) & MASK(16)))
#define SEXT26(x) (((Word) (x)) & SIGN(26) ? \
(((Word) (x)) | ~MASK(26)) : \
(((Word) (x)) & MASK(26)))
 
 
#define OP_ADD 0x00
#define OP_ADDI 0x01
#define OP_SUB 0x02
#define OP_SUBI 0x03
 
#define OP_MUL 0x04
#define OP_MULI 0x05
#define OP_MULU 0x06
#define OP_MULUI 0x07
#define OP_DIV 0x08
#define OP_DIVI 0x09
#define OP_DIVU 0x0A
#define OP_DIVUI 0x0B
#define OP_REM 0x0C
#define OP_REMI 0x0D
#define OP_REMU 0x0E
#define OP_REMUI 0x0F
 
#define OP_AND 0x10
#define OP_ANDI 0x11
#define OP_OR 0x12
#define OP_ORI 0x13
#define OP_XOR 0x14
#define OP_XORI 0x15
#define OP_XNOR 0x16
#define OP_XNORI 0x17
 
#define OP_SLL 0x18
#define OP_SLLI 0x19
#define OP_SLR 0x1A
#define OP_SLRI 0x1B
#define OP_SAR 0x1C
#define OP_SARI 0x1D
 
#define OP_LDHI 0x1F
 
#define OP_BEQ 0x20
#define OP_BNE 0x21
#define OP_BLE 0x22
#define OP_BLEU 0x23
#define OP_BLT 0x24
#define OP_BLTU 0x25
#define OP_BGE 0x26
#define OP_BGEU 0x27
#define OP_BGT 0x28
#define OP_BGTU 0x29
 
#define OP_J 0x2A
#define OP_JR 0x2B
#define OP_JAL 0x2C
#define OP_JALR 0x2D
 
#define OP_TRAP 0x2E
#define OP_RFX 0x2F
 
#define OP_LDW 0x30
#define OP_LDH 0x31
#define OP_LDHU 0x32
#define OP_LDB 0x33
#define OP_LDBU 0x34
 
#define OP_STW 0x35
#define OP_STH 0x36
#define OP_STB 0x37
 
#define OP_MVFS 0x38
#define OP_MVTS 0x39
#define OP_TBS 0x3A
#define OP_TBWR 0x3B
#define OP_TBRI 0x3C
#define OP_TBWI 0x3D
 
 
typedef struct {
char *name;
int format;
Byte opcode;
} Instr;
 
 
extern Instr instrTbl[];
extern Instr *instrCodeTbl[];
 
 
void initInstrTable(void);
Instr *lookupInstr(char *name);
 
 
#endif /* _INSTR_H_ */
/monitor/monitor-digilent/start.s
0,0 → 1,389
;
; start.s -- ECO32 ROM monitor startup and support routines
;
 
.set dmapaddr,0xC0000000 ; base of directly mapped addresses
.set stacktop,0xC4000000 ; monitor stack is at top of memory
 
.set PSW,0 ; reg # of PSW
.set TLB_INDEX,1 ; reg # of TLB Index
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo
.set TLB_ENTRIES,32 ; number of TLB entries
 
.set USER_CONTEXT_SIZE,36*4 ; size of user context
 
;***************************************************************
 
.import _ecode
.import _edata
.import _ebss
 
.import kbdinit
.import kbdinchk
.import kbdin
 
.import dspinit
.import dspoutchk
.import dspout
 
.import serinit
.import ser0inchk
.import ser0in
.import ser0outchk
.import ser0out
 
.import sctcapctl
.import sctioctl
.import sctcapser
.import sctioser
 
.import main
 
.export _bcode
.export _bdata
.export _bbss
 
.export cinchk
.export cin
.export coutchk
.export cout
.export sinchk
.export sin
.export soutchk
.export sout
.export dskcap
.export dskio
 
.export getTLB_HI
.export getTLB_LO
.export setTLB
 
.export saveState
.export monitorReturn
 
.import userContext
.export resume
 
;***************************************************************
 
.code
_bcode:
 
.data
_bdata:
 
.bss
_bbss:
 
;***************************************************************
 
.code
.align 4
 
reset:
j start
 
interrupt:
j isr
 
userMiss:
j umsr
 
;***************************************************************
 
.code
.align 4
 
cinchk:
j kbdinchk
; j ser0inchk
 
cin:
j kbdin
; j ser0in
 
coutchk:
j dspoutchk
; j ser0outchk
 
cout:
j dspout
; j ser0out
 
sinchk:
j ser0inchk
 
sin:
j ser0in
 
soutchk:
j ser0outchk
 
sout:
j ser0out
 
dskcap:
j dcap
 
dskio:
j dio
 
;***************************************************************
 
.code
.align 4
 
start:
; force CPU into a defined state
mvts $0,PSW ; disable interrupts and user mode
 
; initialize TLB
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries
add $8,$0,dmapaddr ; by impossible virtual page number
add $9,$0,$0
add $10,$0,TLB_ENTRIES
tlbloop:
mvts $8,TLB_ENTRY_HI
mvts $9,TLB_INDEX
tbwi
add $8,$8,0x1000 ; all entries must be different
add $9,$9,1
bne $9,$10,tlbloop
 
; copy data segment
add $10,$0,_bdata ; lowest dst addr to be written to
add $8,$0,_edata ; one above the top dst addr
sub $9,$8,$10 ; $9 = size of data segment
add $9,$9,_ecode ; data is waiting right after code
j cpytest
cpyloop:
ldw $11,$9,0 ; src addr in $9
stw $11,$8,0 ; dst addr in $8
cpytest:
sub $8,$8,4 ; downward
sub $9,$9,4
bgeu $8,$10,cpyloop
 
; clear bss segment
add $8,$0,_bbss ; start with first word of bss
add $9,$0,_ebss ; this is one above the top
j clrtest
clrloop:
stw $0,$8,0 ; dst addr in $8
add $8,$8,4 ; upward
clrtest:
bltu $8,$9,clrloop
 
; now do some useful work
add $29,$0,stacktop ; setup monitor stack
jal dspinit ; init display
jal kbdinit ; init keyboard
jal serinit ; init serial interface
jal main ; enter command loop
 
; main should never return
j start ; just to be sure...
 
;***************************************************************
 
; Word getTLB_HI(int index)
getTLB_HI:
mvts $4,TLB_INDEX
tbri
mvfs $2,TLB_ENTRY_HI
jr $31
 
; Word getTLB_LO(int index)
getTLB_LO:
mvts $4,TLB_INDEX
tbri
mvfs $2,TLB_ENTRY_LO
jr $31
 
; void setTLB(int index, Word entryHi, Word entryLo)
setTLB:
mvts $4,TLB_INDEX
mvts $5,TLB_ENTRY_HI
mvts $6,TLB_ENTRY_LO
tbwi
jr $31
 
;***************************************************************
 
; int dskcap(int dskno)
dcap:
bne $4,$0,dcapser
j sctcapctl
dcapser:
j sctcapser
 
; int dskio(int dskno, char cmd, int sct, Word addr, int nscts)
dio:
bne $4,$0,dioser
add $4,$5,$0
add $5,$6,$0
add $6,$7,$0
ldw $7,$29,16
j sctioctl
dioser:
add $4,$5,$0
add $5,$6,$0
add $6,$7,$0
ldw $7,$29,16
j sctioser
 
;***************************************************************
 
.code
.align 4
 
; Bool saveState(MonitorState *msp)
; always return 'true' here
saveState:
stw $31,$4,0*4 ; return address
stw $29,$4,1*4 ; stack pointer
stw $16,$4,2*4 ; local variables
stw $17,$4,3*4
stw $18,$4,4*4
stw $19,$4,5*4
stw $20,$4,6*4
stw $21,$4,7*4
stw $22,$4,8*4
stw $23,$4,9*4
add $2,$0,1
jr $31
 
; load state when re-entering monitor
; this appears as if returning from saveState
; but the return value is 'false' here
loadState:
ldw $8,$0,monitorReturn
beq $8,$0,loadState ; fatal error: monitor state lost
ldw $31,$8,0*4 ; return address
ldw $29,$8,1*4 ; stack pointer
ldw $16,$8,2*4 ; local variables
ldw $17,$8,3*4
ldw $18,$8,4*4
ldw $19,$8,5*4
ldw $20,$8,6*4
ldw $21,$8,7*4
ldw $22,$8,8*4
ldw $23,$8,9*4
add $2,$0,0
jr $31
 
.bss
.align 4
 
; extern MonitorState *monitorReturn
monitorReturn:
.space 4
 
; extern UserContext userContext
userContext:
.space USER_CONTEXT_SIZE
 
;***************************************************************
 
.code
.align 4
 
; void resume(void)
; use userContext to load state
resume:
mvts $0,PSW
add $28,$0,userContext
.nosyn
ldw $8,$28,33*4 ; tlbIndex
mvts $8,TLB_INDEX
ldw $8,$28,34*4 ; tlbWntryHi
mvts $8,TLB_ENTRY_HI
ldw $8,$28,35*4 ; tlbEntryLo
mvts $8,TLB_ENTRY_LO
;ldw $0,$28,0*4 ; registers
ldw $1,$28,1*4
ldw $2,$28,2*4
ldw $3,$28,3*4
ldw $4,$28,4*4
ldw $5,$28,5*4
ldw $6,$28,6*4
ldw $7,$28,7*4
ldw $8,$28,8*4
ldw $9,$28,9*4
ldw $10,$28,10*4
ldw $11,$28,11*4
ldw $12,$28,12*4
ldw $13,$28,13*4
ldw $14,$28,14*4
ldw $15,$28,15*4
ldw $16,$28,16*4
ldw $17,$28,17*4
ldw $18,$28,18*4
ldw $19,$28,19*4
ldw $20,$28,20*4
ldw $21,$28,21*4
ldw $22,$28,22*4
ldw $23,$28,23*4
ldw $24,$28,24*4
ldw $25,$28,25*4
ldw $26,$28,26*4
ldw $27,$28,27*4
;ldw $28,$28,28*4
ldw $29,$28,29*4
ldw $30,$28,30*4
ldw $31,$28,31*4
ldw $28,$28,32*4 ; psw
mvts $28,PSW
rfx
.syn
 
; interrupt entry
; use userContext to store state
isr:
umsr:
.nosyn
ldhi $28,userContext
or $28,$28,userContext
stw $0,$28,0*4 ; registers
stw $1,$28,1*4
stw $2,$28,2*4
stw $3,$28,3*4
stw $4,$28,4*4
stw $5,$28,5*4
stw $6,$28,6*4
stw $7,$28,7*4
stw $8,$28,8*4
stw $9,$28,9*4
stw $10,$28,10*4
stw $11,$28,11*4
stw $12,$28,12*4
stw $13,$28,13*4
stw $14,$28,14*4
stw $15,$28,15*4
stw $16,$28,16*4
stw $17,$28,17*4
stw $18,$28,18*4
stw $19,$28,19*4
stw $20,$28,20*4
stw $21,$28,21*4
stw $22,$28,22*4
stw $23,$28,23*4
stw $24,$28,24*4
stw $25,$28,25*4
stw $26,$28,26*4
stw $27,$28,27*4
stw $28,$28,28*4
stw $29,$28,29*4
stw $30,$28,30*4
stw $31,$28,31*4
mvfs $8,PSW
stw $8,$28,32*4 ; psw
mvfs $8,TLB_INDEX
stw $8,$28,33*4 ; tlbIndex
mvfs $8,TLB_ENTRY_HI
stw $8,$28,34*4 ; tlbEntryHi
mvfs $8,TLB_ENTRY_LO
stw $8,$28,35*4 ; tlbEntryLo
.syn
j loadState
/monitor/monitor-digilent/load.c
0,0 → 1,223
/*
* load.c -- load S-record file from serial line
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "load.h"
#include "serial.h"
#include "cpu.h"
#include "mmu.h"
 
 
#define NUM_TRIES 10
#define WAIT_DELAY 350000
 
#define SYN ((unsigned char) 's')
#define ACK ((unsigned char) 'a')
 
#define LINE_SIZE 520
 
 
static Byte line[LINE_SIZE];
 
 
static Word getByte(int index) {
Word hi, lo;
 
hi = line[index + 0];
if (hi >= '0' && hi <= '9') {
hi -= '0';
} else
if (hi >= 'A' && hi <= 'F') {
hi -= 'A' - 10;
} else
if (hi >= 'a' && hi <= 'f') {
hi -= 'a' - 10;
} else {
return -1;
}
lo = line[index + 1];
if (lo >= '0' && lo <= '9') {
lo -= '0';
} else
if (lo >= 'A' && lo <= 'F') {
lo -= 'A' - 10;
} else
if (lo >= 'a' && lo <= 'f') {
lo -= 'a' - 10;
} else {
return -1;
}
return (hi << 4) | lo;
}
 
 
static void serialOut(int serno, Word c) {
if (serno == 0) {
ser0out(c);
} else {
ser1out(c);
}
}
 
 
static int serialChk(int serno) {
if (serno == 0) {
return ser0inchk();
} else {
return ser1inchk();
}
}
 
 
static Word serialIn(int serno) {
if (serno == 0) {
return ser0in();
} else {
return ser1in();
}
}
 
 
void load(int serno) {
int i, j;
Bool run;
int type;
int count;
Word chksum;
Word addr;
Byte b;
 
printf("Trying to connect to load server...\n");
for (i = 0; i < NUM_TRIES; i++) {
serialOut(serno, SYN);
for (j = 0; j < WAIT_DELAY; j++) {
if (serialChk(serno) != 0) {
break;
}
}
if (j < WAIT_DELAY) {
break;
}
printf("Request timed out...\n");
}
if (i == NUM_TRIES ||
serialIn(serno) != ACK) {
printf("Unable to establish connection to load server.\n");
return;
}
serialOut(serno, ACK);
printf("Connected to load server.\n");
run = true;
while (run) {
serialOut(serno, 'r');
for (i = 0; i < LINE_SIZE; i++) {
line[i] = serialIn(serno);
if (line[i] == '\n') {
break;
}
}
if (i == LINE_SIZE) {
printf("Error: too many characters in S-record!\n");
break;
}
line[i] = '\0';
printf("%s\n", line);
if (line[0] != 'S') {
printf("Error: malformed S-record!\n");
break;
}
type = line[1];
count = getByte(2);
if (i != 2 * count + 4) {
printf("Error: inconsistent byte count in S-record!\n");
break;
}
chksum = 0;
for (j = 2; j < i; j += 2) {
chksum += getByte(j);
}
if ((chksum & 0xFF) != 0xFF) {
printf("Error: wrong checksum in S-record!\n");
break;
}
switch (type) {
case '0':
/* S0 record: header (skip) */
break;
case '1':
/* S1 record: 2 byte load address + data (load data) */
addr = (getByte( 4) << 8) |
(getByte( 6) << 0);
addr |= 0xC0000000;
for (j = 0; j < count - 3; j++) {
b = getByte(2 * j + 8);
mmuWriteByte(addr + j, b);
}
break;
case '2':
/* S2 record: 3 byte load address + data (load data) */
addr = (getByte( 4) << 16) |
(getByte( 6) << 8) |
(getByte( 8) << 0);
addr |= 0xC0000000;
for (j = 0; j < count - 4; j++) {
b = getByte(2 * j + 10);
mmuWriteByte(addr + j, b);
}
break;
case '3':
/* S3 record: 4 byte load address + data (load data) */
addr = (getByte( 4) << 24) |
(getByte( 6) << 26) |
(getByte( 8) << 8) |
(getByte(10) << 0);
addr |= 0xC0000000;
for (j = 0; j < count - 5; j++) {
b = getByte(2 * j + 12);
mmuWriteByte(addr + j, b);
}
break;
case '5':
/* S5 record: record count (skip) */
break;
case '7':
/* S7 record: 4 byte start address (set PC, stop loading) */
addr = (getByte( 4) << 24) |
(getByte( 6) << 26) |
(getByte( 8) << 8) |
(getByte(10) << 0);
addr |= 0xC0000000;
cpuSetPC(addr);
run = false;
break;
case '8':
/* S8 record: 3 byte start address (set PC, stop loading) */
addr = (getByte( 4) << 16) |
(getByte( 6) << 8) |
(getByte( 8) << 0);
addr |= 0xC0000000;
cpuSetPC(addr);
run = false;
break;
case '9':
/* S9 record: 2 byte start address (set PC, stop loading) */
addr = (getByte( 4) << 8) |
(getByte( 6) << 0);
addr |= 0xC0000000;
cpuSetPC(addr);
run = false;
break;
default:
/* unknown type of S-record */
printf("Error: unknown type of S-record!\n");
run = false;
break;
}
}
serialOut(serno, 'q');
printf("Connection to load server closed.\n");
}
/monitor/monitor-digilent/keyboard.s
0,0 → 1,149
;
; keyboard.s -- a PC keyboard as input device
;
 
;***************************************************************
 
.set kbdbase,0xF0200000 ; keyboard base address
 
; .import cout
; .import byteout
 
.import xltbl1 ; kbd translation table 1
.import xltbl2 ; kbd translation table 2
 
.export kbdinit ; initialize keyboard
.export kbdinchk ; check if input available
.export kbdin ; do keyboard input
 
;***************************************************************
 
.code
.align 4
 
kbdinit:
jr $31
 
kbdinchk:
add $8,$0,kbdbase
ldw $2,$8,0
and $2,$2,1
jr $31
 
kbdin:
sub $29,$29,12
stw $31,$29,8
stw $16,$29,4
stw $17,$29,0
kbdin0:
jal kbdinp
add $16,$2,$0 ; key 1 in $16
add $8,$0,0xF0
bne $16,$8,kbdin2
kbdin1:
jal kbdinp
j kbdin0
kbdin2:
jal kbdinp
add $17,$2,$0 ; key 2 in $17
beq $17,$16,kbdin2
add $8,$0,0xF0
beq $17,$8,kbdin3
j kbdin5
kbdin3:
jal kbdinp
bne $2,$16,kbdin2
kbdin4:
add $4,$16,$0 ; use key 1
add $5,$0,xltbl1 ; with translation table 1
jal xlat
j kbdx
kbdin5:
jal kbdinp
add $8,$0,0xF0
bne $2,$8,kbdin5
kbdin6:
jal kbdinp
beq $2,$16,kbdin7
beq $2,$17,kbdin9
j kbdin5
kbdin7:
jal kbdinp
add $8,$0,0xF0
bne $2,$8,kbdin7
kbdin8:
jal kbdinp
bne $2,$17,kbdin7
j kbdin11
kbdin9:
jal kbdinp
add $8,$0,0xF0
bne $2,$8,kbdin9
kbdin10:
jal kbdinp
bne $2,$16,kbdin9
j kbdin11
kbdin11:
add $8,$0,0x12 ; left shift key
beq $16,$8,kbdin12
add $8,$0,0x59 ; right shift key
beq $16,$8,kbdin12
add $8,$0,0x14 ; ctrl key
beq $16,$8,kbdin14
j kbdin13
kbdin12:
add $4,$17,$0 ; use key 2
add $5,$0,xltbl2 ; with translation table 2
jal xlat
j kbdx
kbdin13:
add $4,$16,$0 ; use key 1
add $5,$0,xltbl1 ; with translation table 1
jal xlat
j kbdx
kbdin14:
add $4,$17,$0 ; use key 2
add $5,$0,xltbl1 ; with translation table 1
jal xlat
and $2,$2,0xFF-0x60 ; then reset bits 0x60
j kbdx
kbdx:
ldw $17,$29,0
ldw $16,$29,4
ldw $31,$29,8
add $29,$29,12
jr $31
 
kbdinp:
add $8,$0,kbdbase
kbdinp1:
ldw $9,$8,0
and $9,$9,1
beq $9,$0,kbdinp1 ; wait until character ready
ldw $2,$8,4 ; get character
add $9,$0,0xE0
beq $2,$9,kbdinp1 ; ignore E0 prefix
add $9,$0,0xE1
beq $2,$9,kbdinp1 ; as well as E1 prefix
jr $31
 
xlat:
sub $29,$29,8
stw $31,$29,4
stw $16,$29,0
and $16,$4,0xFF
add $8,$16,$5
ldbu $2,$8,0
bne $2,$0,xlat1
; add $4,$0,'<'
; jal cout
; add $4,$16,$0
; jal byteout
; add $4,$0,'>'
; jal cout
add $2,$16,$0
xlat1:
ldw $16,$29,0
ldw $31,$29,4
add $29,$29,8
jr $31
/monitor/monitor-digilent/disasm.c
0,0 → 1,138
/*
* disasm.c -- disassembler
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "instr.h"
#include "disasm.h"
 
 
static char instrBuffer[100];
 
 
static void disasmN(char *opName, Word immed) {
if (immed == 0) {
sprintf(instrBuffer, "%-7s", opName);
} else {
sprintf(instrBuffer, "%-7s %08X", opName, immed);
}
}
 
 
static void disasmRH(char *opName, int r1, Half immed) {
sprintf(instrBuffer, "%-7s $%d,%04X", opName, r1, immed);
}
 
 
static void disasmRHH(char *opName, int r1, Half immed) {
sprintf(instrBuffer, "%-7s $%d,%08X", opName, r1, (Word) immed << 16);
}
 
 
static void disasmRRH(char *opName, int r1, int r2, Half immed) {
sprintf(instrBuffer, "%-7s $%d,$%d,%04X", opName, r1, r2, immed);
}
 
 
static void disasmRRS(char *opName, int r1, int r2, Half immed) {
sprintf(instrBuffer, "%-7s $%d,$%d,%s%04X", opName, r1, r2,
SIGN(16) & immed ? "-" : "+",
SIGN(16) & immed ? -(signed)SEXT16(immed) : SEXT16(immed));
}
 
 
static void disasmRRR(char *opName, int r1, int r2, int r3) {
sprintf(instrBuffer, "%-7s $%d,$%d,$%d", opName, r1, r2, r3);
}
 
 
static void disasmRRB(char *opName, int r1, int r2, Half offset, Word locus) {
sprintf(instrBuffer, "%-7s $%d,$%d,%08X", opName,
r1, r2, (locus + 4) + (SEXT16(offset) << 2));
}
 
 
static void disasmJ(char *opName, Word offset, Word locus) {
sprintf(instrBuffer, "%-7s %08X", opName,
(locus + 4) + (SEXT26(offset) << 2));
}
 
 
static void disasmJR(char *opName, int r1) {
sprintf(instrBuffer, "%-7s $%d", opName, r1);
}
 
 
char *disasm(Word instr, Word locus) {
Byte opcode;
Instr *ip;
 
opcode = (instr >> 26) & 0x3F;
ip = instrCodeTbl[opcode];
if (ip == NULL) {
disasmN("???", 0);
} else {
switch (ip->format) {
case FORMAT_N:
disasmN(ip->name, instr & 0x03FFFFFF);
break;
case FORMAT_RH:
disasmRH(ip->name, (instr >> 16) & 0x1F, instr & 0x0000FFFF);
break;
case FORMAT_RHH:
disasmRHH(ip->name, (instr >> 16) & 0x1F, instr & 0x0000FFFF);
break;
case FORMAT_RRH:
disasmRRH(ip->name, (instr >> 16) & 0x1F,
(instr >> 21) & 0x1F, instr & 0x0000FFFF);
break;
case FORMAT_RRS:
disasmRRS(ip->name, (instr >> 16) & 0x1F,
(instr >> 21) & 0x1F, instr & 0x0000FFFF);
break;
case FORMAT_RRR:
disasmRRR(ip->name, (instr >> 11) & 0x1F,
(instr >> 21) & 0x1F, (instr >> 16) & 0x1F);
break;
case FORMAT_RRX:
if ((opcode & 1) == 0) {
/* the FORMAT_RRR variant */
disasmRRR(ip->name, (instr >> 11) & 0x1F,
(instr >> 21) & 0x1F, (instr >> 16) & 0x1F);
} else {
/* the FORMAT_RRH variant */
disasmRRH(ip->name, (instr >> 16) & 0x1F,
(instr >> 21) & 0x1F, instr & 0x0000FFFF);
}
break;
case FORMAT_RRY:
if ((opcode & 1) == 0) {
/* the FORMAT_RRR variant */
disasmRRR(ip->name, (instr >> 11) & 0x1F,
(instr >> 21) & 0x1F, (instr >> 16) & 0x1F);
} else {
/* the FORMAT_RRS variant */
disasmRRS(ip->name, (instr >> 16) & 0x1F,
(instr >> 21) & 0x1F, instr & 0x0000FFFF);
}
break;
case FORMAT_RRB:
disasmRRB(ip->name, (instr >> 21) & 0x1F,
(instr >> 16) & 0x1F, instr & 0x0000FFFF, locus);
break;
case FORMAT_J:
disasmJ(ip->name, instr & 0x03FFFFFF, locus);
break;
case FORMAT_JR:
disasmJR(ip->name, (instr >> 21) & 0x1F);
break;
default:
printf("illegal entry in instruction table\n");
break;
}
}
return instrBuffer;
}
/monitor/monitor-digilent/sctio-ctl.s
0,0 → 1,133
;
; sctio-ctl.s -- disk sector I/O for disk made available by disk controller
;
 
;***************************************************************
 
.set dskbase,0xF0400000 ; disk base address
.set dskctrl,0 ; control register
.set dskcnt,4 ; count register
.set dsksct,8 ; sector register
.set dskcap,12 ; capacity register
.set dskbuf,0x00080000 ; disk buffer
 
.set ctrlstrt,0x01 ; start bit
.set ctrlien,0x02 ; interrupt enable bit
.set ctrlwrt,0x04 ; write bit
.set ctrlerr,0x08 ; error bit
.set ctrldone,0x10 ; done bit
.set ctrlrdy,0x20 ; ready bit
 
.set sctsize,512 ; sector size in bytes
 
.set retries,1000000 ; retries to get disk ready
 
.export sctcapctl ; determine disk capacity
.export sctioctl ; do disk I/O
 
;***************************************************************
 
.code
.align 4
 
sctcapctl:
add $8,$0,retries ; set retry count
add $9,$0,dskbase
sctcap1:
ldw $10,$9,dskctrl
and $10,$10,ctrlrdy ; ready?
bne $10,$0,sctcapok ; yes - jump
sub $8,$8,1
bne $8,$0,sctcap1 ; try again
add $2,$0,0 ; no disk found
j sctcapx
sctcapok:
ldw $2,$9,dskcap ; get disk capacity
sctcapx:
jr $31
 
sctioctl:
sub $29,$29,24
stw $31,$29,20
stw $16,$29,16
stw $17,$29,12
stw $18,$29,8
stw $19,$29,4
stw $20,$29,0
add $16,$4,$0 ; command
add $17,$5,$0 ; sector number
add $18,$6,0xC0000000 ; memory address, virtualized
add $19,$7,$0 ; number of sectors
 
add $8,$0,'r'
beq $16,$8,sctrd
add $8,$0,'w'
beq $16,$8,sctwr
add $2,$0,0xFF ; illegal command
j sctx
 
sctrd:
add $2,$0,$0 ; return ok
beq $19,$0,sctx ; if no (more) sectors
add $8,$0,dskbase
add $9,$0,1
stw $9,$8,dskcnt ; number of sectors
stw $17,$8,dsksct ; sector number on disk
add $9,$0,ctrlstrt
stw $9,$8,dskctrl ; start command
sctrd1:
ldw $2,$8,dskctrl
and $9,$2,ctrldone ; done?
beq $9,$0,sctrd1 ; no - wait
and $9,$2,ctrlerr ; error?
bne $9,$0,sctx ; yes - leave
add $8,$0,dskbase + dskbuf ; transfer data
add $9,$0,sctsize
sctrd2:
ldw $10,$8,0 ; from disk buffer
stw $10,$18,0 ; to memory
add $8,$8,4
add $18,$18,4
sub $9,$9,4
bne $9,$0,sctrd2
add $17,$17,1 ; increment sector number
sub $19,$19,1 ; decrement number of sectors
j sctrd ; next sector
 
sctwr:
add $2,$0,$0 ; return ok
beq $19,$0,sctx ; if no (more) sectors
add $8,$0,dskbase + dskbuf ; transfer data
add $9,$0,sctsize
sctwr1:
ldw $10,$18,0 ; from memory
stw $10,$8,0 ; to disk buffer
add $18,$18,4
add $8,$8,4
sub $9,$9,4
bne $9,$0,sctwr1
add $8,$0,dskbase
add $9,$0,1
stw $9,$8,dskcnt ; number of sectors
stw $17,$8,dsksct ; sector number on disk
add $9,$0,ctrlwrt | ctrlstrt
stw $9,$8,dskctrl ; start command
sctwr2:
ldw $2,$8,dskctrl
and $9,$2,ctrldone ; done?
beq $9,$0,sctwr2 ; no - wait
and $9,$2,ctrlerr ; error?
bne $9,$0,sctx ; yes - leave
add $17,$17,1 ; increment sector number
sub $19,$19,1 ; decrement number of sectors
j sctwr ; next sector
 
sctx:
ldw $20,$29,0
ldw $19,$29,4
ldw $18,$29,8
ldw $17,$29,12
ldw $16,$29,16
ldw $31,$29,20
add $29,$29,24
jr $31
/monitor/monitor-digilent/load.h
0,0 → 1,13
/*
* load.h -- load S-record file from serial line
*/
 
 
#ifndef _LOAD_H_
#define _LOAD_H_
 
 
void load(int serno);
 
 
#endif /* _LOAD_H_ */
/monitor/monitor-digilent/romlib.c
0,0 → 1,636
/*
* romlib.c -- the ROM library
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "start.h"
 
 
/**************************************************************/
 
 
/*
* This is only for debugging.
* Place a breakpoint at the very beginning of this routine
* and call it wherever you want to break execution.
*/
void debugBreak(void) {
}
 
 
/**************************************************************/
 
 
/*
* Count the length of a string (without terminating null character).
*/
int strlen(const char *s) {
const char *p;
 
p = s;
while (*p != '\0') {
p++;
}
return p - s;
}
 
 
/*
* Compare two strings.
* Return a number < 0, = 0, or > 0 iff the first string is less
* than, equal to, or greater than the second one, respectively.
*/
int strcmp(const char *s, const char *t) {
while (*s == *t) {
if (*s == '\0') {
return 0;
}
s++;
t++;
}
return *s - *t;
}
 
 
/*
* Copy string t to string s (includes terminating null character).
*/
char *strcpy(char *s, const char *t) {
char *p;
 
p = s;
while ((*p = *t) != '\0') {
p++;
t++;
}
return s;
}
 
 
/*
* Append string t to string s.
*/
char *strcat(char *s, const char *t) {
char *p;
 
p = s;
while (*p != '\0') {
p++;
}
while ((*p = *t) != '\0') {
p++;
t++;
}
return s;
}
 
 
/*
* Locate character c in string s.
*/
char *strchr(const char *s, char c) {
while (*s != c) {
if (*s == '\0') {
return NULL;
}
s++;
}
return (char *) s;
}
 
 
/*
* Extract the next token from the string s, delimited
* by any character from the delimiter string t.
*/
char *strtok(char *s, const char *t) {
static char *p;
char *q;
 
if (s != NULL) {
p = s;
} else {
p++;
}
while (*p != '\0' && strchr(t, *p) != NULL) {
p++;
}
if (*p == '\0') {
return NULL;
}
q = p++;
while (*p != '\0' && strchr(t, *p) == NULL) {
p++;
}
if (*p != '\0') {
*p = '\0';
} else {
p--;
}
return q;
}
 
 
/**************************************************************/
 
 
/*
* Determine if a character is 'white space'.
*/
static Bool isspace(char c) {
Bool res;
 
switch (c) {
case ' ':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
res = true;
break;
default:
res = false;
break;
}
return res;
}
 
 
/*
* Check for valid digit, and convert to value.
*/
static Bool checkDigit(char c, int base, int *value) {
if (c >= '0' && c <= '9') {
*value = c - '0';
} else
if (c >= 'A' && c <= 'Z') {
*value = c - 'A' + 10;
} else
if (c >= 'a' && c <= 'z') {
*value = c - 'a' + 10;
} else {
return false;
}
return *value < base;
}
 
 
/*
* Convert initial part of string to unsigned long integer.
*/
unsigned long strtoul(const char *s, char **endp, int base) {
unsigned long res;
int sign;
int digit;
 
res = 0;
while (isspace(*s)) {
s++;
}
if (*s == '+') {
sign = 1;
s++;
} else
if (*s == '-') {
sign = -1;
s++;
} else {
sign = 1;
}
if (base == 0 || base == 16) {
if (*s == '0' &&
(*(s + 1) == 'x' || *(s + 1) == 'X')) {
/* base is 16 */
s += 2;
base = 16;
} else {
/* base is 0 or 16, but number does not start with "0x" */
if (base == 0) {
if (*s == '0') {
s++;
base = 8;
} else {
base = 10;
}
} else {
/* take base as is */
}
}
} else {
/* take base as is */
}
while (checkDigit(*s, base, &digit)) {
res *= base;
res += digit;
s++;
}
if (endp != NULL) {
*endp = (char *) s;
}
return sign * res;
}
 
 
/**************************************************************/
 
 
/*
* Exchange two array items of a given size.
*/
static void xchg(char *p, char *q, int size) {
char t;
 
while (size--) {
t = *p;
*p++ = *q;
*q++ = t;
}
}
 
 
/*
* This is a recursive version of quicksort.
*/
static void sort(char *l, char *r, int size,
int (*cmp)(const void *, const void *)) {
char *i;
char *j;
char *x;
 
i = l;
j = r;
x = l + (((r - l) / size) / 2) * size;
do {
while (cmp(i, x) < 0) {
i += size;
}
while (cmp(x, j) < 0) {
j -= size;
}
if (i <= j) {
/* exchange array elements i and j */
/* attention: update x if it is one of these */
if (x == i) {
x = j;
} else
if (x == j) {
x = i;
}
xchg(i, j, size);
i += size;
j -= size;
}
} while (i <= j);
if (l < j) {
sort(l, j, size, cmp);
}
if (i < r) {
sort(i, r, size, cmp);
}
}
 
 
/*
* External interface for the quicksort algorithm.
*/
void qsort(void *base, int n, int size,
int (*cmp)(const void *, const void*)) {
sort((char *) base, (char *) base + (n - 1) * size, size, cmp);
}
 
 
/**************************************************************/
 
 
/*
* Input a character from the console.
*/
char getchar(void) {
return cin();
}
 
 
/*
* Output a character on the console.
* Replace LF by CR/LF.
*/
void putchar(char c) {
if (c == '\n') {
cout('\r');
}
cout(c);
}
 
 
/*
* Output a string on the console.
* Replace LF by CR/LF.
*/
void puts(const char *s) {
while (*s != '\0') {
putchar(*s);
s++;
}
}
 
 
/**************************************************************/
 
 
/*
* Count the number of characters needed to represent
* a given number in base 10.
*/
static int countPrintn(long n) {
long a;
int res;
 
res = 0;
if (n < 0) {
res++;
n = -n;
}
a = n / 10;
if (a != 0) {
res += countPrintn(a);
}
return res + 1;
}
 
 
/*
* Output a number in base 10.
*/
static void *printn(void *(*emit)(void *, char), void *arg,
int *nchar, long n) {
long a;
 
if (n < 0) {
arg = emit(arg, '-');
(*nchar)++;
n = -n;
}
a = n / 10;
if (a != 0) {
arg = printn(emit, arg, nchar, a);
}
arg = emit(arg, n % 10 + '0');
(*nchar)++;
return arg;
}
 
 
/*
* Count the number of characters needed to represent
* a given number in a given base.
*/
static int countPrintu(unsigned long n, unsigned long b) {
unsigned long a;
int res;
 
res = 0;
a = n / b;
if (a != 0) {
res += countPrintu(a, b);
}
return res + 1;
}
 
 
/*
* Output a number in a given base.
*/
static void *printu(void *(*emit)(void *, char), void *arg,
int *nchar, unsigned long n, unsigned long b,
Bool upperCase) {
unsigned long a;
 
a = n / b;
if (a != 0) {
arg = printu(emit, arg, nchar, a, b, upperCase);
}
if (upperCase) {
arg = emit(arg, "0123456789ABCDEF"[n % b]);
(*nchar)++;
} else {
arg = emit(arg, "0123456789abcdef"[n % b]);
(*nchar)++;
}
return arg;
}
 
 
/*
* Output a number of filler characters.
*/
static void *fill(void *(*emit)(void *, char), void *arg,
int *nchar, int numFillers, char filler) {
while (numFillers-- > 0) {
arg = emit(arg, filler);
(*nchar)++;
}
return arg;
}
 
 
/*
* This function does the real work of formatted printing.
*/
static int doPrintf(void *(*emit)(void *, char), void *arg,
const char *fmt, va_list ap) {
int nchar;
char c;
int n;
long ln;
unsigned int u;
unsigned long lu;
char *s;
Bool negFlag;
char filler;
int width, count;
 
nchar = 0;
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
return nchar;
}
arg = emit(arg, c);
nchar++;
}
c = *fmt++;
if (c == '-') {
negFlag = true;
c = *fmt++;
} else {
negFlag = false;
}
if (c == '0') {
filler = '0';
c = *fmt++;
} else {
filler = ' ';
}
width = 0;
while (c >= '0' && c <= '9') {
width *= 10;
width += c - '0';
c = *fmt++;
}
if (c == 'd') {
n = va_arg(ap, int);
count = countPrintn(n);
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printn(emit, arg, &nchar, n);
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
u = va_arg(ap, int);
count = countPrintu(u,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printu(emit, arg, &nchar, u,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
c == 'X');
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'l') {
c = *fmt++;
if (c == 'd') {
ln = va_arg(ap, long);
count = countPrintn(ln);
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printn(emit, arg, &nchar, ln);
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
lu = va_arg(ap, long);
count = countPrintu(lu,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printu(emit, arg, &nchar, lu,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
c == 'X');
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else {
arg = emit(arg, 'l');
nchar++;
arg = emit(arg, c);
nchar++;
}
} else
if (c == 's') {
s = va_arg(ap, char *);
count = strlen(s);
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
while ((c = *s++) != '\0') {
arg = emit(arg, c);
nchar++;
}
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'c') {
c = va_arg(ap, char);
arg = emit(arg, c);
nchar++;
} else {
arg = emit(arg, c);
nchar++;
}
}
/* never reached */
return 0;
}
 
 
/*
* Emit a character to the console.
*/
static void *emitToConsole(void *dummy, char c) {
putchar(c);
return dummy;
}
 
 
/*
* Formatted output with a variable argument list.
*/
int vprintf(const char *fmt, va_list ap) {
int n;
 
n = doPrintf(emitToConsole, NULL, fmt, ap);
return n;
}
 
 
/*
* Formatted output.
*/
int printf(const char *fmt, ...) {
int n;
va_list ap;
 
va_start(ap, fmt);
n = vprintf(fmt, ap);
va_end(ap);
return n;
}
 
 
/*
* Emit a character to a buffer.
*/
static void *emitToBuffer(void *bufptr, char c) {
*(char *)bufptr = c;
return (char *) bufptr + 1;
}
 
 
/*
* Formatted output into a buffer with a variable argument list.
*/
int vsprintf(char *s, const char *fmt, va_list ap) {
int n;
 
n = doPrintf(emitToBuffer, s, fmt, ap);
s[n] = '\0';
return n;
}
 
 
/*
* Formatted output into a buffer.
*/
int sprintf(char *s, const char *fmt, ...) {
int n;
va_list ap;
 
va_start(ap, fmt);
n = vsprintf(s, fmt, ap);
va_end(ap);
return n;
}
/monitor/monitor-digilent/serial.h
0,0 → 1,21
/*
* serial.s -- the serial line interface
*/
 
 
#ifndef _SERIAL_H_
#define _SERIAL_H_
 
 
int ser0inchk(void);
int ser0in(void);
int ser0outchk(void);
void ser0out(int c);
 
int ser1inchk(void);
int ser1in(void);
int ser1outchk(void);
void ser1out(int c);
 
 
#endif /* _SERIAL_H_ */
/monitor/monitor-digilent/display.s
0,0 → 1,225
;
; display.s -- a memory-mapped alphanumerical display
;
 
;***************************************************************
 
.set dspbase,0xF0100000 ; display base address
 
.export dspinit ; initialize display
.export dspoutchk ; check for output possible
.export dspout ; do display output
 
;***************************************************************
 
.code
.align 4
 
; initialize display
dspinit:
sub $29,$29,4
stw $31,$29,0
jal clrscr
add $8,$0,scrrow
stw $0,$8,0
add $8,$0,scrcol
stw $0,$8,0
jal calcp
jal stcrs
ldw $31,$29,0
add $29,$29,4
jr $31
 
; check if a character can be written
dspoutchk:
add $2,$0,1
jr $31
 
; output a character on the display
dspout:
sub $29,$29,8
stw $31,$29,4
stw $16,$29,0
and $16,$4,0xFF
jal rmcrs
add $8,$0,' '
bltu $16,$8,dspout2
add $8,$0,scrptr
ldw $9,$8,0
or $16,$16,0x07 << 8
stw $16,$9,0
add $9,$9,4
stw $9,$8,0
add $8,$0,scrcol
ldw $9,$8,0
add $9,$9,1
stw $9,$8,0
add $10,$0,80
bne $9,$10,dspout1
jal docr
jal dolf
dspout1:
jal stcrs
ldw $16,$29,0
ldw $31,$29,4
add $29,$29,8
jr $31
 
dspout2:
add $8,$0,0x0D
bne $16,$8,dspout3
jal docr
j dspout1
 
dspout3:
add $8,$0,0x0A
bne $16,$8,dspout4
jal dolf
j dspout1
 
dspout4:
add $8,$0,0x08
bne $16,$8,dspout5
jal dobs
j dspout1
 
dspout5:
j dspout1
 
; do carriage return
docr:
sub $29,$29,4
stw $31,$29,0
add $8,$0,scrcol
stw $0,$8,0
jal calcp
ldw $31,$29,0
add $29,$29,4
jr $31
 
; do linefeed
dolf:
sub $29,$29,4
stw $31,$29,0
add $8,$0,scrrow
ldw $9,$8,0
add $10,$0,29
beq $9,$10,dolf1
add $9,$9,1
stw $9,$8,0
jal calcp
j dolf2
dolf1:
jal scrscr
dolf2:
ldw $31,$29,0
add $29,$29,4
jr $31
 
; do backspace
dobs:
sub $29,$29,4
stw $31,$29,0
add $8,$0,scrcol
ldw $9,$8,0
beq $9,$0,dobs1
sub $9,$9,1
stw $9,$8,0
jal calcp
dobs1:
ldw $31,$29,0
add $29,$29,4
jr $31
 
; remove cursor
rmcrs:
add $8,$0,scrptr
ldw $8,$8,0
add $9,$0,scrchr
ldw $10,$9,0
stw $10,$8,0
jr $31
 
; set cursor
stcrs:
add $8,$0,scrptr
ldw $8,$8,0
add $9,$0,scrchr
ldw $10,$8,0
stw $10,$9,0
add $10,$0,(0x87 << 8) | '_'
stw $10,$8,0
jr $31
 
; calculate screen pointer based on row and column
calcp:
add $9,$0,dspbase
add $8,$0,scrrow
ldw $10,$8,0
sll $10,$10,7+2
add $9,$9,$10
add $8,$0,scrcol
ldw $10,$8,0
sll $10,$10,0+2
add $9,$9,$10
add $8,$0,scrptr
stw $9,$8,0
jr $31
 
; clear screen
clrscr:
add $11,$0,(0x07 << 8) | ' '
add $8,$0,dspbase
add $9,$0,30
clrscr1:
add $10,$0,80
clrscr2:
stw $11,$8,0
add $8,$8,4
sub $10,$10,1
bne $10,$0,clrscr2
add $8,$8,(128-80)*4
sub $9,$9,1
bne $9,$0,clrscr1
jr $31
 
; scroll screen
scrscr:
add $8,$0,dspbase
add $9,$0,29
scrscr1:
add $10,$0,80
scrscr2:
ldw $11,$8,128*4
stw $11,$8,0
add $8,$8,4
sub $10,$10,1
bne $10,$0,scrscr2
add $8,$8,(128-80)*4
sub $9,$9,1
bne $9,$0,scrscr1
add $11,$0,(0x07 << 8) | ' '
add $10,$0,80
scrscr3:
stw $11,$8,0
add $8,$8,4
sub $10,$10,1
bne $10,$0,scrscr3
jr $31
 
;***************************************************************
 
.bss
.align 4
 
scrptr:
.word 0
 
scrrow:
.word 0
 
scrcol:
.word 0
 
scrchr:
.word 0
/monitor/monitor-digilent/disasm.h
0,0 → 1,13
/*
* disasm.h -- disassembler
*/
 
 
#ifndef _DISASM_H_
#define _DISASM_H_
 
 
char *disasm(Word instr, Word locus);
 
 
#endif /* _DISASM_H_ */
/monitor/monitor-digilent/end.s
0,0 → 1,19
;
; end.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/monitor/monitor-digilent/cpu.c
0,0 → 1,367
/*
* cpu.c -- execute instructions
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "instr.h"
#include "cpu.h"
#include "mmu.h"
#include "start.h"
 
 
#define RR(n) r[n]
#define WR(n,d) ((void) ((n) != 0 ? r[n] = (d) : (d)))
 
#define BREAK (OP_TRAP << 26)
 
 
/**************************************************************/
 
 
static Word pc; /* program counter */
static Word psw; /* processor status word */
static Word r[32]; /* general purpose registers */
 
static Bool breakSet; /* breakpoint set if true */
static Word breakAddr; /* if breakSet, this is where */
 
 
/**************************************************************/
 
 
Word cpuGetPC(void) {
return pc;
}
 
 
void cpuSetPC(Word addr) {
pc = addr;
}
 
 
Word cpuGetReg(int regnum) {
return RR(regnum & 0x1F);
}
 
 
void cpuSetReg(int regnum, Word value) {
WR(regnum & 0x1F, value);
}
 
 
Word cpuGetPSW(void) {
return psw;
}
 
 
void cpuSetPSW(Word value) {
psw = value;
}
 
 
Bool cpuTestBreak(void) {
return breakSet;
}
 
 
Word cpuGetBreak(void) {
return breakAddr;
}
 
 
void cpuSetBreak(Word addr) {
breakAddr = addr;
breakSet = true;
}
 
 
void cpuResetBreak(void) {
breakSet = false;
}
 
 
/**************************************************************/
 
 
static char *cause[32] = {
/* 0 */ "terminal 0 transmitter interrupt",
/* 1 */ "terminal 0 receiver interrupt",
/* 2 */ "terminal 1 transmitter interrupt",
/* 3 */ "terminal 1 receiver interrupt",
/* 4 */ "keyboard interrupt",
/* 5 */ "unknown interrupt",
/* 6 */ "unknown interrupt",
/* 7 */ "unknown interrupt",
/* 8 */ "disk interrupt",
/* 9 */ "unknown interrupt",
/* 10 */ "unknown interrupt",
/* 11 */ "unknown interrupt",
/* 12 */ "unknown interrupt",
/* 13 */ "unknown interrupt",
/* 14 */ "timer interrupt",
/* 15 */ "unknown interrupt",
/* 16 */ "bus timeout exception",
/* 17 */ "illegal instruction exception",
/* 18 */ "privileged instruction exception",
/* 19 */ "divide instruction exception",
/* 20 */ "trap instruction exception",
/* 21 */ "TLB miss exception",
/* 22 */ "TLB write exception",
/* 23 */ "TLB invalid exception",
/* 24 */ "illegal address exception",
/* 25 */ "privileged address exception",
/* 26 */ "unknown exception",
/* 27 */ "unknown exception",
/* 28 */ "unknown exception",
/* 29 */ "unknown exception",
/* 30 */ "unknown exception",
/* 31 */ "unknown exception"
};
 
 
char *exceptionToString(int exception) {
if (exception < 0 ||
exception >= sizeof(cause)/sizeof(cause[0])) {
return "<exception number out of bounds>";
}
return cause[exception];
}
 
 
/**************************************************************/
 
 
static Byte stepType[64] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 0x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 0x20 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 3, 4, 1, 0,
/* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
 
 
static Bool evalCond(int cc, Word a, Word b) {
switch (cc) {
case 0:
/* equal */
if (a == b) {
return true;
}
break;
case 1:
/* not equal */
if (a != b) {
return true;
}
break;
case 2:
/* less or equal (signed) */
if ((signed int) a <= (signed int) b) {
return true;
}
break;
case 3:
/* less or equal (unsigned) */
if (a <= b) {
return true;
}
break;
case 4:
/* less than (signed) */
if ((signed int) a < (signed int) b) {
return true;
}
break;
case 5:
/* less than (unsigned) */
if (a < b) {
return true;
}
break;
case 6:
/* greater or equal (signed) */
if ((signed int) a >= (signed int) b) {
return true;
}
break;
case 7:
/* greater or equal (unsigned) */
if (a >= b) {
return true;
}
break;
case 8:
/* greater than (signed) */
if ((signed int) a > (signed int) b) {
return true;
}
break;
case 9:
/* greater than (unsigned) */
if (a > b) {
return true;
}
break;
default:
printf("cannot compute condition code %d\n", cc);
break;
}
return false;
}
 
 
Bool cpuStep(void) {
Word instr;
int opcode;
int reg1, reg2;
Half immed;
Word offset;
Bool canStep;
Word nextAddr;
Word nextInstr;
int i;
MonitorState stepState;
MonitorState *origReturn;
 
instr = mmuReadWord(pc);
opcode = (instr >> 26) & 0x3F;
reg1 = (instr >> 21) & 0x1F;
reg2 = (instr >> 16) & 0x1F;
immed = instr & 0x0000FFFF;
offset = instr & 0x03FFFFFF;
canStep = true;
switch (stepType[opcode]) {
case 1:
/* next instruction follows current one */
nextAddr = pc + 4;
break;
case 2:
/* next instruction conditionally reached by PC relative branch */
nextAddr = pc + 4;
if (evalCond(opcode - OP_BEQ, RR(reg1), RR(reg2))) {
nextAddr += SEXT16(immed) << 2;
}
break;
case 3:
/* next instruction reached by PC relative jump */
nextAddr = pc + 4 + (SEXT26(offset) << 2);
break;
case 4:
/* next instruction reached by jump to register contents */
nextAddr = RR(reg1);
break;
default:
printf("cannot single-step instruction with opcode 0x%02X\n",
opcode);
canStep = false;
break;
}
if (!canStep) {
return false;
}
nextInstr = mmuReadWord(nextAddr);
mmuWriteWord(nextAddr, BREAK);
for (i = 0; i < 32; i++) {
userContext.reg[i] = RR(i);
}
userContext.reg[30] = pc;
userContext.psw = psw & ~PSW_V;
userContext.tlbIndex = mmuGetIndex();
userContext.tlbHi = mmuGetEntryHi();
userContext.tlbLo = mmuGetEntryLo();
if (saveState(&stepState)) {
origReturn = monitorReturn;
monitorReturn = &stepState;
resume();
}
monitorReturn = origReturn;
for (i = 0; i < 32; i++) {
WR(i, userContext.reg[i]);
}
pc = userContext.reg[30];
psw = userContext.psw | (psw & PSW_V);
mmuSetIndex(userContext.tlbIndex);
mmuSetEntryHi(userContext.tlbHi);
mmuSetEntryLo(userContext.tlbLo);
mmuWriteWord(nextAddr, nextInstr);
if (nextAddr == pc) {
return true;
}
if ((psw & PSW_V) == 0) {
printf("unexpected %s occurred\n",
exceptionToString((psw & PSW_PRIO_MASK) >> 16));
return false;
}
if ((psw & PSW_PRIO_MASK) >> 16 == 21 &&
(mmuGetEntryHi() & 0x80000000) == 0) {
pc = 0xC0000008;
} else {
pc = 0xC0000004;
}
return true;
}
 
 
Bool cpuRun(void) {
Word instr;
int i;
MonitorState runState;
MonitorState *origReturn;
 
if (breakSet && breakAddr == pc) {
/* single-step one instruction */
if (!cpuStep()) {
return false;
}
}
while (1) {
if (breakSet) {
instr = mmuReadWord(breakAddr);
mmuWriteWord(breakAddr, BREAK);
}
for (i = 0; i < 32; i++) {
userContext.reg[i] = RR(i);
}
userContext.reg[30] = pc;
userContext.psw = psw & ~PSW_V;
userContext.tlbIndex = mmuGetIndex();
userContext.tlbHi = mmuGetEntryHi();
userContext.tlbLo = mmuGetEntryLo();
if (saveState(&runState)) {
origReturn = monitorReturn;
monitorReturn = &runState;
resume();
}
monitorReturn = origReturn;
for (i = 0; i < 32; i++) {
WR(i, userContext.reg[i]);
}
pc = userContext.reg[30];
psw = userContext.psw | (psw & PSW_V);
mmuSetIndex(userContext.tlbIndex);
mmuSetEntryHi(userContext.tlbHi);
mmuSetEntryLo(userContext.tlbLo);
if (breakSet) {
mmuWriteWord(breakAddr, instr);
}
if (breakSet && breakAddr == pc) {
return true;
}
if ((psw & PSW_V) == 0) {
printf("unexpected %s occurred\n",
exceptionToString((psw & PSW_PRIO_MASK) >> 16));
return false;
}
if ((psw & PSW_PRIO_MASK) >> 16 == 21 &&
(mmuGetEntryHi() & 0x80000000) == 0) {
pc = 0xC0000008;
} else {
pc = 0xC0000004;
}
}
/* never reached */
return false;
}
/monitor/monitor-digilent/getline.c
0,0 → 1,136
/*
* getline.c -- line input
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "getline.h"
 
 
#define MAX_HISTORY 20
 
 
static char history[MAX_HISTORY][80];
static int historyIndex; /* next line to be written */
 
 
/*
* Get a line from the console.
*/
char *getLine(char *prompt) {
static char line[80];
int index;
int historyPointer;
char c;
int i;
 
printf(prompt);
index = 0;
historyPointer = historyIndex;
while (1) {
c = getchar();
switch (c) {
case '\r':
putchar('\n');
line[index] = '\0';
return line;
case '\b':
case 0x7F:
if (index == 0) {
break;
}
putchar('\b');
putchar(' ');
putchar('\b');
index--;
break;
case 'P' & ~0x40:
if (historyPointer == historyIndex) {
line[index] = '\0';
strcpy(history[historyIndex], line);
}
i = historyPointer - 1;
if (i == -1) {
i = MAX_HISTORY - 1;
}
if (i == historyIndex) {
putchar('\a');
break;
}
if (history[i][0] == '\0') {
putchar('\a');
break;
}
historyPointer = i;
strcpy(line, history[historyPointer]);
printf("\r");
for (i = 0; i < 79; i++) {
printf(" ");
}
printf("\r");
printf(prompt);
printf(line);
index = strlen(line);
break;
case 'N' & ~0x40:
if (historyPointer == historyIndex) {
putchar('\a');
break;
}
i = historyPointer + 1;
if (i == MAX_HISTORY) {
i = 0;
}
historyPointer = i;
strcpy(line, history[historyPointer]);
printf("\r");
for (i = 0; i < 79; i++) {
printf(" ");
}
printf("\r");
printf(prompt);
printf(line);
index = strlen(line);
break;
default:
if (c == '\t') {
c = ' ';
}
if (c < 0x20 || c > 0x7E) {
break;
}
putchar(c);
line[index++] = c;
break;
}
}
/* never reached */
return NULL;
}
 
 
/*
* Add a line to the history.
* Don't do this if the line is empty, or if its
* contents exactly match the previous line.
*/
void addHist(char *line) {
int lastWritten;
 
if (*line == '\0') {
return;
}
lastWritten = historyIndex - 1;
if (lastWritten == -1) {
lastWritten = MAX_HISTORY - 1;
}
if (strcmp(history[lastWritten], line) == 0) {
return;
}
strcpy(history[historyIndex], line);
if (++historyIndex == MAX_HISTORY) {
historyIndex = 0;
}
}
/monitor/monitor-digilent/romlib.h
0,0 → 1,34
/*
* romlib.h -- the ROM library
*/
 
 
#ifndef _ROMLIB_H_
#define _ROMLIB_H_
 
 
void debugBreak(void);
 
int strlen(const char *s);
int strcmp(const char *s, const char *t);
char *strcpy(char *s, const char *t);
char *strcat(char *s, const char *t);
char *strchr(const char *s, char c);
char *strtok(char *s, const char *t);
 
unsigned long strtoul(const char *s, char **endp, int base);
 
void qsort(void *base, int n, int size,
int (*cmp)(const void *, const void *));
 
char getchar(void);
void putchar(char c);
void puts(const char *s);
 
int vprintf(const char *fmt, va_list ap);
int printf(const char *fmt, ...);
int vsprintf(char *s, const char *fmt, va_list ap);
int sprintf(char *s, const char *fmt, ...);
 
 
#endif /* _ROMLIB_H_ */
/monitor/monitor-digilent/cpu.h
0,0 → 1,40
/*
* cpu.h -- execute instructions
*/
 
 
#ifndef _CPU_H_
#define _CPU_H_
 
 
#define PSW_V 0x08000000 /* interrupt vector bit in PSW */
#define PSW_UM 0x04000000 /* user mode enable bit in PSW */
#define PSW_PUM 0x02000000 /* previous value of PSW_UM */
#define PSW_OUM 0x01000000 /* old value of PSW_UM */
#define PSW_IE 0x00800000 /* interrupt enable bit in PSW */
#define PSW_PIE 0x00400000 /* previous value of PSW_IE */
#define PSW_OIE 0x00200000 /* old value of PSW_IE */
#define PSW_PRIO_MASK 0x001F0000 /* bits to encode IRQ prio in PSW */
 
 
Word cpuGetPC(void);
void cpuSetPC(Word addr);
 
Word cpuGetReg(int regnum);
void cpuSetReg(int regnum, Word value);
 
Word cpuGetPSW(void);
void cpuSetPSW(Word value);
 
Bool cpuTestBreak(void);
Word cpuGetBreak(void);
void cpuSetBreak(Word addr);
void cpuResetBreak(void);
 
char *exceptionToString(int exception);
 
Bool cpuStep(void);
Bool cpuRun(void);
 
 
#endif /* _CPU_H_ */
/monitor/monitor-digilent/getline.h
0,0 → 1,14
/*
* getline.h -- line input
*/
 
 
#ifndef _GETLINE_H_
#define _GETLINE_H_
 
 
char *getLine(char *prompt);
void addHist(char *line);
 
 
#endif /* _GETLINE_H_ */
/monitor/monitor-digilent/Makefile
0,0 → 1,31
#
# Makefile for ECO32 ROM monitor
#
 
BUILD = ../../build
 
SRC = start.s main.c command.c instr.c asm.c disasm.c \
load.c boot.c cpu.c mmu.c getline.c romlib.c \
keyboard.s ../kbdtbls/kbdtbls.s display.s \
serial.s sctio-ctl.s sctio-ser.s end.s
 
.PHONY: all install clean
 
all: monitor.bin monitor.exo
 
install: monitor.bin monitor.exo
mkdir -p $(BUILD)/monitor
cp monitor.bin $(BUILD)/monitor
cp monitor.exo $(BUILD)/monitor
 
monitor.exo: monitor.bin
$(BUILD)/bin/bin2exo 0 monitor.bin monitor.exo
 
monitor.bin: $(SRC)
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC3FFC000 \
-Wl-m -Wlmonitor.map -o monitor.bin $(SRC)
 
clean:
rm -f *~
rm -f monitor.map monitor.bin
rm -f monitor.exo
/monitor/monitor-digilent/serial.s
0,0 → 1,98
;
; serial.s -- the serial line interface
;
 
;***************************************************************
 
.set ser0base,0xF0300000 ; serial line 0 base address
.set ser1base,0xF0301000 ; serial line 1 base address
 
.export serinit ; initialize serial interface
 
.export ser0inchk ; line 0 input check
.export ser0in ; line 0 input
.export ser0outchk ; line 0 output check
.export ser0out ; line 0 output
 
.export ser1inchk ; line 1 input check
.export ser1in ; line 1 input
.export ser1outchk ; line 1 output check
.export ser1out ; line 1 output
 
;***************************************************************
 
.code
.align 4
 
serinit:
jr $31
 
;***************************************************************
 
.code
.align 4
 
ser0inchk:
add $8,$0,ser0base
ldw $2,$8,0
and $2,$2,1
jr $31
 
ser0in:
add $8,$0,ser0base
ser0in1:
ldw $9,$8,0
and $9,$9,1
beq $9,$0,ser0in1
ldw $2,$8,4
jr $31
 
ser0outchk:
add $8,$0,ser0base
ldw $2,$8,8
and $2,$2,1
jr $31
 
ser0out:
add $8,$0,ser0base
ser0out1:
ldw $9,$8,8
and $9,$9,1
beq $9,$0,ser0out1
stw $4,$8,12
jr $31
 
;***************************************************************
 
.code
.align 4
 
ser1inchk:
add $8,$0,ser1base
ldw $2,$8,0
and $2,$2,1
jr $31
 
ser1in:
add $8,$0,ser1base
ser1in1:
ldw $9,$8,0
and $9,$9,1
beq $9,$0,ser1in1
ldw $2,$8,4
jr $31
 
ser1outchk:
add $8,$0,ser1base
ldw $2,$8,8
and $2,$2,1
jr $31
 
ser1out:
add $8,$0,ser1base
ser1out1:
ldw $9,$8,8
and $9,$9,1
beq $9,$0,ser1out1
stw $4,$8,12
jr $31
/monitor/monitor-digilent/monitor.exo
0,0 → 1,2259
S214000000A800000CA800009BA800009AA8001A07E9
S214000010A8001A0BA8001AFBA8001AFCA8001B9937
S214000020A8001B9DA8001BA3A8001BA7A800003BB8
S214000030A800003DE4000000E40000037C01C000CE
S2140000400001400000004800040A0020E408000206
S214000050E4090001F400000005081000052900016D
S214000060852AFFFA7C01C3FF4C21C0000001500026
S2140000707C01C3FF4C21DA7000014000090A4800E9
S2140000807C01E0004C2172B001214800A80000026B
S214000090C12B0000D50B00000D0800040D2900043C
S2140000A09D0AFFFB7C01C3FF4C21DA700001400073
S2140000B07C01C3FF4C21E5E000014800A8000002D7
S2140000C0D5000000050800049509FFFD7C01C4006A
S2140000D00001E800B0001ABBB00019D3B0001B68DE
S2140000E0B000008FABFFFFD3E4040001F000000077
S2140000F0E0020002AFE00000E4040001F0000000AF
S214000100E0020003AFE00000E4040001E4050002A2
S214000110E4060003F4000000AFE000008480000165
S214000120A8001B8CA8001BE78480000500A0200008
S21400013000C0280000E03000C3A70010A8001B93F2
S21400014000A0200000C0280000E03000C3A7001078
S214000150A8001C11D49F0000D49D0004D490000871
S214000160D491000CD4920010D4930014D4940018A8
S214000170D495001CD4960020D497002404020001D5
S214000180AFE000007C01C3FF4C21DA7000200800BD
S214000190C02800008100FFFBC11F0000C11D000435
S2140001A0C1100008C111000CC1120010C1130014C8
S2140001B0C1140018C115001CC1160020C117002468
S2140001C004020000AFE00000E40000007C01C3FF72
S2140001D04C21DA740001E000C3880084E4080001C2
S2140001E0C3880088E4080002C388008CE408000383
S2140001F0C3810004C3820008C383000CC3840010BC
S214000200C3850014C3860018C387001CC38800205B
S214000210C3890024C38A0028C38B002CC38C0030FB
S214000220C38D0034C38E0038C38F003CC39000409B
S214000230C3910044C3920048C393004CC39400503B
S214000240C3950054C3960058C397005CC3980060DB
S214000250C3990064C39A0068C39B006CC39D007476
S214000260C39E0078C39F007CC39C0080E41C0000F3
S214000270BC0000007C1CC3FF4F9CDA74D7800000D3
S214000280D7810004D7820008D783000CD7840010DB
S214000290D7850014D7860018D787001CD78800207B
S2140002A0D7890024D78A0028D78B002CD78C00301B
S2140002B0D78D0034D78E0038D78F003CD7900040BB
S2140002C0D7910044D7920048D793004CD79400505B
S2140002D0D7950054D7960058D797005CD7980060FB
S2140002E0D7990064D79A0068D79B006CD79C00709B
S2140002F0D79D0074D79E0078D79F007CE00800004A
S214000300D7880080E0080001D7880084E008000253
S214000310D7880088E0080003D788008CABFFFF99D9
S2140003200FBD0020D7B70010D7BF00147C01C3FF55
S2140003304C21C00900012000B0001901B000088758
S2140003407C01C00000012000B0001007A8000009D2
S2140003507C01C3FF4C21C00000012000B000134107
S2140003600002B80000172000B00014180017200084
S214000370B000084FABFFFFF600001000C3B7001038
S214000380C3BF001407BD0020AFE000000FBD002073
S214000390D7BF00107C01C3FF4C21CF4A00012000CC
S2140003A0B00018E77C01C3FF4C21CF3600012000C7
S2140003B0B00018E37C01C3FF4C21CF1A00012000D7
S2140003C0B00018DF7C01C3FF4C21CF0600012000DF
S2140003D0B00018DB7C01C3FF4C21CEF000012000EA
S2140003E0B00018D77C01C3FF4C21CED000012000FE
S2140003F0B00018D37C01C3FF4C21CEAC0001200016
S214000400B00018CF7C01C3FF4C21CE950001200020
S214000410B00018CB7C01C3FF4C21CE7E000120002B
S214000420B00018C77C01C3FF4C21CE660001200037
S214000430B00018C37C01C3FF4C21CE490001200048
S214000440B00018BF7C01C3FF4C21CE320001200053
S214000450B00018BB7C01C3FF4C21CE120001200067
S214000460B00018B77C01C3FF4C21CDEE0001200080
S214000470B00018B37C01C3FF4C21CDCE0001200094
S214000480B00018AF7C01C3FF4C21CDAD00012000A9
S214000490B00018AB7C01C3FF4C21CD8C00012000BE
S2140004A0B00018A77C01C3FF4C21CD6D00012000D1
S2140004B0B00018A37C01C3FF4C21CD4400012000EE
S2140004C0B000189FC3BF001007BD0020AFE00000BB
S2140004D00FBD0020D7BF00107C01C3FF4C21CD17F5
S2140004E000012000B00018967C01C3FF4C21CCEE22
S2140004F000012000B0001892C3BF001007BD002006
S214000500AFE000000FBD0020D7BF00107C01C3FF86
S2140005104C21CCB600012000B0001889C3BF0010E3
S21400052007BD0020AFE000000FBD0020D7BF0010C1
S2140005307C01C3FF4C21CC8900012000B00018804C
S2140005407C01C3FF4C21CC5800012000B000187C71
S214000550C3BF001007BD0020AFE000000FBD0020A5
S214000560D7BF00107C01C3FF4C21CC1F0001200028
S214000570B00018737C01C3FF4C21CBE200012000C1
S214000580B000186F7C01C3FF4C21CBA200012000F5
S214000590B000186BC3BF001007BD0020AFE000001E
S2140005A00FBD0020D7BF00107C01C3FF4C21CB81BC
S2140005B000012000B00018627C01C3FF4C21CB581C
S2140005C000012000B000185EC3BF001007BD002069
S2140005D0AFE000000FBD0020D7BF00107C01C3FFB6
S2140005E04C21CB3000012000B00018557C01C3FF21
S2140005F04C21CAFC00012000B0001851C3BF0010F7
S21400060007BD0020AFE000000FBD0020D7BF0010E0
S2140006107C01C3FF4C21CACB00012000B000184863
S2140006207C01C3FF4C21CA9700012000B00018448B
S214000630C3BF001007BD0020AFE000000FBD0020C4
S214000640D7BF00107C01C3FF4C21CA7A00012000EE
S214000650B000183B7C01C3FF4C21CA5400012000A7
S214000660B0001837C3BF001007BD0020AFE0000081
S2140006700FBD0020D7BF00107C01C3FF4C21CA3637
S21400068000012000B000182E7C01C3FF4C21CA0FC9
S21400069000012000B000182AC3BF001007BD0020CC
S2140006A0AFE000000FBD0020D7BF00107C01C3FFE5
S2140006B04C21C9E700012000B00018217C01C3FFCF
S2140006C04C21C9BE00012000B000181D7C01C3FFEC
S2140006D04C21C98C00012000B0001819C3BF0010BF
S2140006E007BD0020AFE000000FBD0020D7BF001000
S2140006F07C01C3FF4C21C95900012000B00018102E
S2140007007C01C3FF4C21C92200012000B000180C58
S2140007107C01C3FF4C21C8E900012000B000180886
S214000720C3BF001007BD0020AFE000000FBD0020D3
S214000730D7BF00107C01C3FF4C21C8BD00012000BC
S214000740B00017FF7C01C3FF4C21C88D00012000BC
S214000750B00017FB7C01C3FF4C21C85400012000E9
S214000760B00017F7C3BF001007BD0020AFE00000C1
S2140007700FBD0020D7BF00107C01C3FF4C21C8244A
S21400078000012000B00017EE7C01C3FF4C21C7F02B
S21400079000012000B00017EA7C01C3FF4C21C7B35C
S2140007A000012000B00017E6C3BF001007BD002000
S2140007B0AFE000000FBD0020D7BF00107C01C3FFD4
S2140007C04C21C78700012000B00017DD7C01C3FF65
S2140007D04C21C75700012000B00017D97C01C3FF89
S2140007E04C21C71E00012000B00017D5C3BF001063
S2140007F007BD0020AFE000000FBD0020D7BF0010EF
S2140008007C01C3FF4C21C6F700012000B00017CCC6
S2140008107C01C3FF4C21C6C900012000B00017C8E8
S2140008207C01C3FF4C21C68D00012000B00017C418
S2140008307C01C3FF4C21C65000012000B00017C049
S214000840C3BF001007BD0020AFE000000FBD0020B2
S214000850D7BF00107C01C3FF4C21C610000120004A
S214000860B00017B7C3BF001007BD0020AFE0000000
S2140008700FBD0020D7BF00107C01C3FF4C21C5D19F
S21400088000012000B00017AEC3BF001007BD002057
S214000890AFE000000FBD0020D7B70010D7BF001490
S2140008A0D7A40020D7A50024C3A4002007A5001CB9
S2140008B004060010B00013FDC3AF0024D5E200000C
S2140008C0C3B8001CCF180000870000020417000100
S2140008D0A80000010000B80000171000C3B7001001
S2140008E0C3BF001407BD0020AFE000000FBD00200E
S2140008F0D7B70010D7BF0014D7A40020D7A5002470
S214000900C3A4002007A5001C0406000AB00013E7D5
S214000910C3AF00240002C000D5F80000C3B8001C16
S214000920CF1800008700000204170001A80000018D
S2140009300000B80000171000C3B70010C3BF0014B3
S21400094007BD0020AFE000000FBD0020D7B60010A6
S214000950D7B70014D7BF0018B0000E7E0002B8004C
S214000960B0000E97D7A2001C00172000B00011445C
S2140009700002B0000016200000172800B0000BA8E8
S2140009800002C0007C01C3FF4C21C5B1000120005D
S214000990001728000016300000183800B00017684E
S2140009A0C3B60010C3B70014C3BF001807BD0020AD
S2140009B0AFE000000FBD0020D7BF0010B0000E8FC4
S2140009C0D7A2001C7C01C3FF4C21C5AB0001200050
S2140009D0B000175BB0000E84804000067C01C3FFA9
S2140009E04C21C5A600012000C3A5001CB00017546A
S2140009F0A80000047C01C3FF4C21C59D0001200017
S214000A00B000174F7C01C3FF4C21C59B000120009E
S214000A10B000174BC3BF001007BD0020AFE00000BA
S214000A200FBD0020D7B50010D7B60014D7B70018F2
S214000A30D7BF001CB0000E620002B0007C01C3FFEE
S214000A404C21C57600012000B000173D7C01C3FF95
S214000A504C21C57000012000B00017390417001F94
S214000A600418001B82F800080418001A82F8000612
S214000A700418001782F800040418001482F8000214
S214000A800418000F86F800047C01C3FF4C21C56DD6
S214000A9000012000B000172A7C01C3FF4C21C56A64
S214000AA000012000041800016317C00042D8C000EF
S214000AB08300000204150031A80000010415003070
S214000AC000152800B000171E0EF700019AE0FFE49C
S214000AD07C01C3FF4C21C59B00012000B000171805
S214000AE0C3B50010C3B60014C3B70018C3BF001CBC
S214000AF007BD0020AFE000000FBD0020D7B70010F4
S214000B00D7BF0014D7A40020D7A50024C3B800245C
S214000B10040F0001870F0002B3FFFE1CA80000258B
S214000B20C3B80024040F0002870F00210000B8009D
S214000B30A80000130418000C1317C0007C01C3FFA4
S214000B404C21C02800380800C0240000C3B800208C
S214000B50C3050004B0001264844000080418000CAA
S214000B601317C0007C01C3FF4C21C02C00380800BE
S214000B70C0390000B7200000A800000E06F70001EC
S214000B807C01C3FF4C21C0F400200800C0380000E0
S214000B9092F8FFE87C01C3FF4C21C5470001200006
S214000BA0C3B80020C3050004B00016E5A800000185
S214000BB0B3FFFE47C3B70010C3BF001407BD002035
S214000BC0AFE000000FBD0030D7BF0010D7A4003044
S214000BD0D7A50034C3B80034040F0003870F0021E4
S214000BE0C3B80030C304000407A5002CB3FFFF29D8
S214000BF0844000057C01C3FF4C21C5310001200064
S214000C00B00016CFA8000018C3B80030C304000810
S214000C1007A50028B3FFFF1F844000057C01C3FF23
S214000C204C21C51A00012000B00016C5A800000E11
S214000C30C3B8002CC3AF0028030F7000D7AE002443
S214000C400B0FC000D7B800207C01C3FF4C21C502A3
S214000C5000012000C3A50024C3A60020B00016B8DB
S214000C60A8000001B3FFFE27C3BF001007BD003079
S214000C70AFE000000FBD0050D7B60010D7B7001485
S214000C80D7BF0018D7A40050D7A50054C3B8005447
S214000C90040F0001870F0003B0000DAED7A2004C72
S214000CA0A800000FC3B80054040F0002870F000A04
S214000CB0C3B80050C304000407A5004CB3FFFEF5FC
S214000CC0844000077C01C3FF4C21C4F100012000D2
S214000CD0B000169BA800002EB3FFFE13A800002C41
S214000CE0C3B8004C7C01FFFF4C21FFFC4301C00051
S214000CF0D7B8004CB0000DB2D7A20024A80000233D
S214000D0007A4002E7C01C3FF4C21C4E40001280088
S214000D10C3A6004CB00016B307A4002EB00010D136
S214000D200002B800CEF8000083000002040F000A9C
S214000D30870F0001A800001600172000B00011A3BE
S214000D4000172000C3A5004C07A60028B00006AF79
S214000D500002B0000016C000830000067C01C3FF3E
S214000D604C21C4E00001200000162800B0001674D4
S214000D70A8000006C3A4004CC3A50028B000104974
S214000D80C3B8004C07180004D7B8004CABFFFFDC14
S214000D90C3B60010C3B70014C3BF001807BD005089
S214000DA0AFE000000FBD0030D7B60010D7B7001474
S214000DB0D7BF0018D7A40030D7A50034C3B8003476
S214000DC0040F0001870F0005B0000D62D7A2002CAB
S214000DD004180010D7B80028A800002CC3B80034A8
S214000DE0040F0002870F000DC3B80030C3040004D0
S214000DF007A5002CB3FFFEA7844000057C01C3FFB7
S214000E004C21C4F100012000B000164DA80000419E
S214000E1004180010D7B80028A800001CC3B8003477
S214000E20040F0003870F0017C3B80030C304000484
S214000E3007A5002CB3FFFE97844000057C01C3FF86
S214000E404C21C4F100012000B000163DA80000317E
S214000E50C3B80030C304000807A50028B3FFFE8D02
S214000E60844000057C01C3FF4C21C4D10001200052
S214000E70B0001633A8000027C3B800288700000378
S214000E80A8000024B3FFFDB5A8000022C3B8002CBC
S214000E907C01FFFF4C21FFFC4301C000D7B8002CAB
S214000EA0B0000D47D7A200240000B000A80000162E
S214000EB0C3A4002CB0000FF20002B80000172000F8
S214000EC0C3A5002CB0000A560002C0007C01C3FF78
S214000ED04C21C4BE00012000C3A5002C0017300022
S214000EE000183800B0001616C3B8002C070F000410
S214000EF09DF80001A8000007C3B8002C07180004DE
S214000F00D7B8002C06D600010016C000C3AF0028D4
S214000F10970FFFE7C3B60010C3B70014C3BF00188F
S214000F2007BD0030AFE000000FBD0020D7BF0010A7
S214000F30D7A40020D7A50024C3B80024040F0001BE
S214000F40870F0003B0000D3CB3FFFE9AA800001701
S214000F50C3B80024040F0002870F0013C3B8002094
S214000F60C304000407A5001CB3FFFE4A8440000526
S214000F707C01C3FF4C21C4F100012000B00015F035
S214000F80A800000AC3B8001C7C01FFFF4C21FFFC30
S214000F904301C000D7B8001CC3A4001CB0000D1C41
S214000FA0B3FFFE84A8000001B3FFFD7DC3BF0010A1
S214000FB007BD0020AFE000000FBD0020D7B700102F
S214000FC0D7BF0014D7A40020D7A50024C3B8002498
S214000FD0040F0001870F000304180001D7B8001C97
S214000FE0A8000011C3B80024040F0002870F000CED
S214000FF0C3B80020C304000407A5001CB3FFFE25E9
S21400100080400002C3B8001C870000077C01C3FFB5
S2140010104C21C4D100012000B00015C9A800001062
S214001020B3FFFD6CA800000E0000B800A800000288
S214001030B0000E9D06F70001C3B8001C96F8FFFC32
S214001040B0000CC4D7A200187C01C3FF4C21C4AF6B
S21400105000012000C3A50018B00015B9B3FFFE3A82
S214001060C3B70010C3BF001407BD0020AFE00000E8
S2140010700FBD0020D7B70010D7BF0014D7A400209C
S214001080D7A50024C3B80024040F0001870F00036F
S21400109004180001D7B8001CA8000011C3B800242B
S2140010A0040F0002870F000CC3B80020C30400041E
S2140010B007A5001CB3FFFDF780400002C3B8001C64
S2140010C0870000077C01C3FF4C21C4D1000120002B
S2140010D0B000159BA8000009B3FFFD4BA800000751
S2140010E00000B800A8000002B0000D3006F70001AE
S2140010F0C3B8001C96F8FFFCB3FFFE13C3B700107E
S214001100C3BF001407BD0020AFE000000FBD0020E5
S214001110D7BF0010D7A40020D7A50024C3B800244A
S214001120040F0001870F0002B3FFFE07A800001798
S214001130C3B80024040F0002870F0013C3B80020B2
S214001140C304000407A5001CB3FFFDD284400005BD
S2140011507C01C3FF4C21C4F100012000B0001578CB
S214001160A800000AC3B8001C7C01FFFF4C21FFFC4E
S2140011704301C000D7B8001CC3A4001CB0000C7A02
S214001180B3FFFDF1A8000001B3FFFD2CC3BF0010A4
S21400119007BD0020AFE000000FBD0060D7B0001014
S2140011A0D7B10014D7B20018D7B3001CD7B40020AC
S2140011B0D7B50024D7B60028D7B7002CD7BF003045
S2140011C00004B8007C01C3FF4C21C481000120004C
S2140011D07C01080042E1C000830000047C01C3FFDC
S2140011E04C21C47D0001A800A80000037C01C3FFB9
S2140011F04C21C4790001A800001528007C010800D5
S21400120042E1C000830000047C01C3FF4C21C4758A
S2140012100001A000A80000037C01C3FF4C21C4719C
S2140012200001A00000143000B00015457C01C3FF8B
S2140012304C21C443000120007C01040042E1C000B0
S214001240830000047C01C3FF4C21C47D000198008C
S214001250A80000037C01C3FF4C21C479000198005C
S214001260001328007C01040042E1C0008300000453
S2140012707C01C3FF4C21C43E00019000A80000037F
S2140012807C01C3FF4C21C4370001900000123000DF
S214001290B000152B7C01C3FF4C21C40900012000BF
S2140012A07C01020042E1C000830000047C01C3FF11
S2140012B04C21C47D00018800A80000037C01C3FF08
S2140012C04C21C47900018800001128007C0102002E
S2140012D042E1C000830000047C01C3FF4C21C43EF1
S2140012E000018000A80000037C01C3FF4C21C43726
S2140012F00001800000103000B00015117C01C3FF13
S2140013004C21C3DB000120007C01010042E1C0004B
S214001310830000057C01C3FF4C21C47D0001C00092
S214001320D7B8005CA80000047C01C3FF4C21C47938
S2140013300001C000D7B8005CC3A5005C7C010100BA
S21400134042E1C000830000057C01C3FF4C21C43E7F
S2140013500001C000D7B80058A80000047C01C3FFF5
S2140013604C21C4370001C000D7B80058C3A60058A7
S214001370B00014F37C01C3FF4C21C3AD0001200074
S2140013807C01008042E1C000830000057C01C3FFB1
S2140013904C21C47D0001C000D7B80054A80000044A
S2140013A07C01C3FF4C21C4790001C000D7B80054AB
S2140013B0C3A500547C01008042E1C0008300000504
S2140013C07C01C3FF4C21C3A50001C000D7B8005064
S2140013D0A80000047C01C3FF4C21C39C0001C00090
S2140013E0D7B80050C3A60050B00014D57C01C3FF88
S2140013F04C21C36E000120007C01004042E1C00089
S214001400830000057C01C3FF4C21C47D0001C000A1
S214001410D7B8004CA80000047C01C3FF4C21C47957
S2140014200001C000D7B8004CC3A5004C7C010040AA
S21400143042E1C000830000057C01C3FF4C21C3A528
S2140014400001C000D7B80048A80000047C01C3FF14
S2140014504C21C39C0001C000D7B80048C3A6004872
S214001460B00014B77C01C3FF4C21C340000120002C
S2140014707C01002042E1C000830000057C01C3FF20
S2140014804C21C47D0001C000D7B80044A800000469
S2140014907C01C3FF4C21C4790001C000D7B80044CA
S2140014A0C3A500447C01002042E1C0008300000583
S2140014B07C01C3FF4C21C3A50001C000D7B8004083
S2140014C0A80000047C01C3FF4C21C39C0001C0009F
S2140014D0D7B80040C3A60040B00014997C01001F96
S2140014E042E1C0006F18001000182000B0000BD7B3
S2140014F00002C0007C01C3FF4C21C30F0001200086
S2140015007C01001F42E178006DE5001000183000F5
S214001510B000148B0416000F00162000B0000BCB92
S2140015207C01C3FF4C21C2FF0001200000022800FE
S214001530041800016316C00042F8C00083000005CE
S2140015407C01C3FF4C21C47D0001C000D7B8003C1D
S214001550A80000047C01C3FF4C21C4790001C00030
S214001560D7B8003CC3A6003C041800016316C000B0
S21400157042F8C000830000057C01C3FF4C21C3A5D0
S2140015800001C000D7B80038A80000047C01C3FFE3
S2140015904C21C39C0001C000D7B80038C3A7003850
S2140015A0B00014670ED600019AC0FFDBC3B000106F
S2140015B0C3B10014C3B20018C3B3001CC3B40020E8
S2140015C0C3B50024C3B60028C3B7002CC3BF003081
S2140015D007BD0060AFE000000FBD0020D7BF0010C1
S2140015E0D7A40020D7A50024C3B80024040F000108
S2140015F0870F0006B0000B72D7A2001CB3FFFD08D1
S214001600C3A4001CB3FFFEE4A8000019C3B800245E
S214001610040F0002870F0015C3B80020C30400049F
S21400162007A5001CB3FFFC9B844000057C01C3FF9C
S2140016304C21C2F100012000B0001441A800000CAB
S214001640C3B8001C7C010FFF4C21FFFF4301C00004
S214001650D7B8001CC3A4001CB0000B5EB3FFFCF0A0
S214001660C3A4001CB3FFFECCA8000001B3FFFC001F
S214001670C3BF001007BD0020AFE000000FBD003064
S214001680D7B60010D7B70014D7BF0018D7A40030BD
S214001690D7A50034C3B80034040F0001870F001C20
S2140016A00000B0000000B80066F800030316C00093
S2140016B0D7B8002CC3A4002CB0000B30D7A200284B
S2140016C07C01C3FF4C21C2E000012000C3A5002C12
S2140016D0C3A60028B000141A06F700010418000478
S2140016E092F8FFF17C01C3FF4C21C59B000120004E
S2140016F0B000141306D600010418000892D8FFE9BB
S214001700B3FFFCC7B3FFFCABB3FFFC8FA800003BE6
S214001710C3B80034040F0002870F0018C3B80030A7
S214001720C304000407A5002CB3FFFC70804000042F
S214001730C3B8002C93000002040F0020930F00058E
S2140017407C01C3FF4C21C2C700012000B00013FC7F
S214001750A800002AC3A4002CB0000B08D7A20028BB
S2140017607C01C3FF4C21C2BA00012000C3A5002C97
S214001770C3A60028B00013F2A8000020C3B80034A7
S214001780040F0003870F001CC3B80030C304000416
S21400179007A5002CB3FFFC5580400004C3B8002CFE
S2140017A093000002040F0020930F00057C01C3FF86
S2140017B04C21C2C700012000B00013E1A800000FB2
S2140017C0C3B80030C304000807A50028B3FFFC31E7
S2140017D0844000057C01C3FF4C21C2F100012000BB
S2140017E0B00013D7A8000005C3A4002CC3A500288A
S2140017F0B0000AE9A8000001B3FFFBAAC3B60010B8
S214001800C3B70014C3BF001807BD0030AFE0000028
S2140018100FBD0040D7B00010D7B10014D7B20018E3
S214001820D7B3001CD7B40020D7B50024D7B60028FD
S214001830D7B7002CD7BF0030D7A40040D7A50044A8
S214001840C3B80044040F0001870F0005B0000AC1AA
S214001850D7A2003C04180100D7B80038A800002C16
S214001860C3B80044040F0002870F000DC3B8004041
S214001870C304000407A5003CB3FFFC068440000533
S2140018807C01C3FF4C21C4F100012000B00013AC62
S214001890A800007D04180100D7B80038A800001C76
S2140018A0C3B80044040F0003870F0017C3B80040F6
S2140018B0C304000407A5003CB3FFFBF68440000504
S2140018C07C01C3FF4C21C4F100012000B000139C32
S2140018D0A800006DC3B80040C304000807A5003880
S2140018E0B3FFFBEC844000057C01C3FF4C21C4D150
S2140018F000012000B0001392A8000063C3B80038AF
S21400190087000003A8000060B3FFFB77A800005E16
S214001910B0000AABD7A20034C3B8003C7C01FFFF7E
S2140019204C21FFF043018000C3AF0038030FC00016
S2140019300F1300019E7000010413FFFF0A70C00021
S214001940071800106F180004001888000010A00088
S21400195000009000A800004B7C01C3FF4C21C2B2DF
S2140019600001200000142800B00013750000B0002D
S2140019700016C0000298B800C3B8003C96F80001F4
S2140019808EF300057C01C3FF4C21C56D00012000CD
S214001990B000136BA800000900172000B0000D3E31
S2140019A00002C0000018A8007C01C3FF4C21C2AD95
S2140019B00001200046A500FFB00013617C01C3FFB4
S2140019C04C21C2AB00012000B000135D06D600011A
S2140019D00418001092D8FFE67C01C3FF4C21C56DA9
S2140019E000012000B00013560000B0000016C00032
S2140019F00298B800C3B8003C96F800018EF30005C4
S214001A007C01C3FF4C21C2AB00012000B000134C88
S214001A10A800001300172000B0000D1F0002C00031
S214001A200018A80046B800FF040F0020930F000817
S214001A30040F007EA30F00067C01C3FF4C21C56A7D
S214001A400001200046A500FFB000133DA8000004DA
S214001A507C01C3FF4C21C2A900012000B00013384E
S214001A6006D600010418001092D8FFE07C01C3FFE0
S214001A704C21C59B00012000B000133106940010D5
S214001A80065200019251FFB4C3B00010C3B1001457
S214001A90C3B20018C3B3001CC3B40020C3B50024EF
S214001AA0C3B60028C3B7002CC3BF003007BD004034
S214001AB0AFE000000FBD0030D7BF0010D7A4003045
S214001AC0D7A50034B0000A3ED7A20024C3B800341D
S214001AD0040F0001870F000CB0000A1ED7A2002CCE
S214001AE0C3A4002CB0000CE6D7A200287C01C3FFDC
S214001AF04C21C29C00012000C3A5002CC3A60028D0
S214001B00B000130FA8000035C3B80034040F00025D
S214001B10870F0014C3B80030C304000407A5002CC8
S214001B20B3FFFB5C844000057C01C3FF4C21C4F17D
S214001B3000012000B0001302A8000028C3A4002C57
S214001B40B0000CCFD7A200287C01C3FF4C21C29C5A
S214001B5000012000C3A5002CC3A60028B00012F880
S214001B60A800001EC3B80034040F0003870F001A35
S214001B70C3B80030C304000407A5002CB3FFFB4520
S214001B80844000057C01C3FF4C21C4F10001200005
S214001B90B00012EBA8000011C3B80030C304000860
S214001BA007A50020B3FFFB3B844000057C01C3FF74
S214001BB04C21C2F100012000B00012E1A80000078D
S214001BC0C3B80020D7B80028C3A4002CC3A500289B
S214001BD0B0000CB4A8000001B3FFFAD4C3BF0010D5
S214001BE007BD0030AFE000000FBD0030D7BF0010CB
S214001BF0D7A40030D7A50034B00009F1D7A200243E
S214001C00C3B80034040F0001870F000DB00009D1DF
S214001C10D7A2002CC3A4002CB0000C9C0002C0006D
S214001C20DBB8002A7C01C3FF4C21C28F00012000D4
S214001C30C3A5002CCBA6002AB00012C1A80000360F
S214001C40C3B80034040F0002870F0015C3B8003075
S214001C50C304000407A5002CB3FFFB0E8440000558
S214001C607C01C3FF4C21C4F100012000B00012B477
S214001C70A8000029C3A4002CB0000C840002C000F9
S214001C80DBB8002A7C01C3FF4C21C28F0001200074
S214001C90C3A5002CCBA6002AB00012A9A800001EDF
S214001CA0C3B80034040F0003870F001AC3B800300F
S214001CB0C304000407A5002CB3FFFAF68440000511
S214001CC07C01C3FF4C21C4F100012000B000129C2F
S214001CD0A8000011C3B80030C304000807A5002000
S214001CE0B3FFFAEC844000057C01C3FF4C21C2F12F
S214001CF000012000B0001292A8000007C3B8002020
S214001D00DBB8002AC3A4002CCBA5002AB0000C68C0
S214001D10A8000001B3FFFA96C3BF001007BD00304D
S214001D20AFE000000FBD0030D7BF0010D7A40030D2
S214001D30D7A50034B00009A2D7A20024C3B8003447
S214001D40040F0001870F000DB0000982D7A2002CF7
S214001D50C3A4002CB0000C500002C000DFB8002B5B
S214001D607C01C3FF4C21C28200012000C3A5002CC9
S214001D70D3A6002BB0001272A8000036C3B80034F9
S214001D80040F0002870F0015C3B80030C304000418
S214001D9007A5002CB3FFFABF844000057C01C3FFF3
S214001DA04C21C4F100012000B0001265A8000029F3
S214001DB0C3A4002CB0000C380002C000DFB8002B13
S214001DC07C01C3FF4C21C28200012000C3A5002C69
S214001DD0D3A6002BB000125AA800001EC3B80034C9
S214001DE0040F0003870F001AC3B80030C3040004B2
S214001DF007A5002CB3FFFAA7844000057C01C3FFAB
S214001E004C21C4F100012000B000124DA8000011C2
S214001E10C3B80030C304000807A50020B3FFFA9D2E
S214001E20844000057C01C3FF4C21C2F10001200064
S214001E30B0001243A8000007C3B80020DFB8002B8C
S214001E40C3A4002CD3A5002BB0000C1CA8000001D6
S214001E50B3FFFA58C3BF001007BD0030AFE0000064
S214001E600FBD0040D7B60018D7B7001CD7BF00205C
S214001E70D7A40040D7A50044C3B80044040F00010F
S214001E80870F0033D7A0002C07A40030C3A5002C72
S214001E90B0000C2B7C01C3FF4C21C2520001200075
S214001EA0C3A5002CC3A60030C3A70034C3B80038AF
S214001EB08300000204170077A80000010417002D15
S214001EC0D7B70010C3B8003C8300000204160076A3
S214001ED0A80000010416002DD7B60014B000121892
S214001EE0C3B8002C07180001D7B8002CC3B8002CC4
S214001EF0040F0020930FFFE4B0000BF30002C000B5
S214001F007C01C3FF4C21C2410001200000182800BC
S214001F10B000120BB0000BF60002C0007C01C3FF3D
S214001F204C21C2300001200000182800B000120426
S214001F30B0000BF90002C0007C01C3FF4C21C21F99
S214001F400001200000182800B00011FDA800009B2A
S214001F50C3B80044040F0002870F0025C3B8004032
S214001F60C304000407A5002CB3FFFA6080400004F9
S214001F70C3B8002C93000002040F0020930F000546
S214001F807C01C3FF4C21C20C00012000B00011EC04
S214001F90A800008A07A40030C3A5002CB0000BE8F8
S214001FA07C01C3FF4C21C25200012000C3A5002CB7
S214001FB0C3A60030C3A70034C3B8003883000002AD
S214001FC004170077A80000010417002DD7B70010EB
S214001FD0C3B8003C8300000204160076A800000187
S214001FE00416002DD7B60014B00011D5A800007353
S214001FF0C3B80044040F0003870F0002B3FFF9FEC6
S214002000A800006EC3B80044040F0004870F006ADF
S214002010C3B80040C304000407A5002CB3FFFA337E
S21400202080400004C3B8002C93000002040F002078
S214002030930F00057C01C3FF4C21C20C0001200059
S214002040B00011BFA800005DC3B80040C304000C78
S21400205007A50028B3FFFA0F844000057C01C3FFE4
S2140020604C21C2F100012000B00011B5A8000053B9
S21400207007A40030C3A5002CB0000BB1C3B80040C5
S214002080C30400087C01C3FF4C21C20A00012800DB
S214002090B0000D1584400006C3B800287C01FFFF81
S2140020A04C21F0004301C000D7B80030A800002043
S2140020B0C3B80040C30400087C01C3FF4C21C2081B
S2140020C000012800B0000D0884400014C3B80028A2
S2140020D07C01FFFF4C21F0004301C000D7B800345C
S2140020E0C3B8002847180002830000020417000146
S2140020F0A80000010000B800D7B70038C3B8002811
S214002100471800018300000204160001A800000121
S2140021100000B000D7B6003CA80000057C01C3FF55
S2140021204C21C1E100012000B0001185A800002369
S214002130C3A4002C07A80030C1030000C109000496
S214002140D7A30004D7A90008C1030008C109000CE2
S214002150D7A3000CD7A90010C3A50004C3A6000887
S214002160C3A7000CB0000BA87C01C3FF4C21C252D1
S21400217000012000C3A5002CC3A60030C3A700346E
S214002180C3B800388300000204170077A8000001D7
S2140021900417002DD7B70010C3B8003C8300000218
S2140021A004160076A80000010416002DD7B6001409
S2140021B0B0001163A8000001B3FFF98FC3B6001882
S2140021C0C3B7001CC3BF002007BD0040AFE000003F
S2140021D00FBD0020D7BF0010D7A40020D7A500242D
S2140021E0C3B80024040F0002870F0011C3B80020F4
S2140021F0C304000407A5001CB3FFF9BC804000041C
S214002200C3B8001C93000002040F00018B0F0005EA
S2140022107C01C3FF4C21C1C500012000B00011485D
S214002220A8000004C3A4001CB00006A3A800000178
S214002230B3FFF986C3BF001007BD0020AFE0000063
S2140022400FBD0020D7BF0010D7A40020D7A50024BC
S214002250C3B80024040F0002870F0011C3B8002083
S214002260C304000407A5001CB3FFF9A080400004C7
S214002270C3B8001C93000002040F00018B0F00057A
S2140022807C01C3FF4C21C1B000012000B000112C1E
S214002290A8000004C3A4001CB00007E0A8000001CA
S2140022A0B3FFF973C3BF001007BD0020AFE0000006
S2140022B00FBD0050D7B50010D7B60014D7B700181A
S2140022C0D7BF001CD7A400500000A800C3A400502D
S2140022D07C01C3FF4C21C18000012800B0000CBE69
S2140022E00002B000A80000130418000A86B8000513
S2140022F07C01C3FF4C21C16700012000B000111013
S214002300A800002C0015C000071500016718000281
S21400231007AF0028030FC000D716000000002000FB
S2140023207C01C3FF4C21C18000012800B0000CAA2C
S2140023300002B0000016C0008700FFEB86A0000178
S214002340A800001C0000B800A80000140418000C28
S2140023501317C0007C01C3FF4C21C02800380800BA
S214002360C0240000C3A50028B0000C5F8440000A0B
S21400237007A40028001528000418000C1317C00036
S2140023807C01C3FF4C21C03000380800C039000073
S214002390B7200000A800000706F700017C01C3FF75
S2140023A04C21C0F400200800C038000092F8FFE777
S2140023B0B3FFF7F6C3B50010C3B60014C3B70018D2
S2140023C0C3BF001C07BD0050AFE000000FBD0010EB
S2140023D0D7B700006497001876F70018041800694D
S2140023E082F8000DA2F800060418006182F8000AC0
S2140023F092F8000D0418006582F80007A800000A8D
S2140024000418006F82F8000492F80007041800759C
S21400241082F80001A80000047C01C3FF4C21C164BF
S21400242000011000A80000037C01C3FF4C21C1621C
S21400243000011000C3B7000007BD0010AFE00000A9
S2140024400FBD0020D7B70010D7BF0014D7A40020B8
S214002450C3A40020B00007FD0002B8007C01C3FF43
S2140024604C21C59B00012000B00010B5CEE4000052
S214002470B3FFFFD60002C0007C01C3FF4C21C12F72
S214002480000120000018280000173000B00010AC33
S2140024907C01C3FF4C21C0F800012000B00010A84A
S2140024A0C3B70010C3BF001407BD0020AFE0000094
S2140024B00FBD0040D7BF0010D7A4004007A40018E7
S2140024C0B3FFF7248040000807B800187C01C3FF5C
S2140024D04C21DA7000200800D4380000C3A4004065
S2140024E0B3FFFF73A80000097C01C3FF4C21DAF498
S2140024F000200800C03800007C01001F4301C00017
S2140025006F18001000182000B3FFFFCD7C01C3FF3A
S2140025104C21DA7000200800D4200000C3BF001051
S21400252007BD0040AFE000000FBD0020D7BF001081
S214002530D7A40020D7A50024C3B80020C3040000F9
S214002540C3B80024C3050000B0000BE70002C000BB
S214002550C3BF001007BD0020AFE000000FBD002085
S214002560D7B70010D7BF00147C01C3FF4C21CF6043
S214002570000120000405002E0406000C7C01E0008B
S2140025804C21252800013800B0000D770000B80067
S21400259066F800027C01C3FF4C21DB0C0038080003
S2140025A0D420000006F700010418004092F8FFF857
S2140025B00000B800A800002B0418000C1317C00079
S2140025C07C01C3FF4C21CF6800380800D02F0000E4
S2140025D065EF00027C01C3FF4C21CF600301C00001
S2140025E07C01C3FF4C21DB0C002F0800D438000010
S2140025F00418000C1317C0007C01C3FF4C21CF64E5
S21400260000380800C02F0000040E000681EE000609
S2140026107C01C3FF4C21CF6400380800C03800009E
S214002620040F0007870F000E0418000C1317C000D5
S2140026307C01C3FF4C21CF6800380800D02F000073
S21400264065EF00027C01C3FF4C21CF600301C00090
S2140026507C01C3FF4C21DB10002F0800D43800009B
S21400266006F700010017C000040F002E970FFFD2D8
S214002670C3B70010C3BF001407BD0020AFE00000C2
S2140026800FBD0030D7B30010D7B40014D7B500186C
S214002690D7B6001CD7B70020D7BF00240004B80068
S2140026A00000A0000413002DA80000160293C0002E
S2140026B0271600020418000C1316C0007C01C3FF86
S2140026C04C21CF6000380800C02400000017280006
S2140026D0B0000B850002A80086A000060418000CB7
S2140026E01316C0007C01C3FF4C21CF60030110000D
S2140026F0A80000069AA0000206D40001A800000167
S2140027000ED300018A93FFE900001000C3B3001047
S214002710C3B40014C3B50018C3B6001CC3B700206A
S214002720C3BF002407BD0030AFE000000FBD00208F
S214002730D7B70010D7BF0014D7A400200005B800F4
S214002740C3B80020CF180000040F0024830F000237
S21400275000001000A8000013C3B800200704000102
S21400276007A5001C0406000AB0000C500002C000BA
S214002770D6F80000C3B8001CCF1800008300000283
S21400278000001000A8000007C2F800009300000236
S214002790040F0020930F000200001000A8000001A4
S2140027A004020001C3B70010C3BF001407BD002019
S2140027B0AFE000000FBD0020D7B70010D7BF001451
S2140027C0D7A40020D7A50024C3A4002007A5001C7A
S2140027D004060010B0000C35C3AF0024D5E200009C
S2140027E0C3B8001CCF1800008700000204170001C1
S2140027F0A80000010000B80000171000C3B70010C2
S214002800C3BF001407BD0020AFE000000FBD00707E
S214002810D7B40010D7B50014D7B60018D7B7001C29
S214002820D7BF0020D7A40070D7A50074D7A600781D
S2140028300000B000C3A400707C01C3FF4C21D2A8E6
S21400284000012800B0000B640002B800A8000013C6
S2140028500418000A86D800057C01C3FF4C21D2501C
S21400286000200800C0220000A80002D70016C00002
S214002870071600016718000207AF0048030FC000E4
S214002880D7170000000020007C01C3FF4C21D2A80F
S21400289000012800B0000B500002B8000017C0006E
S2140028A08700FFEB86C000057C01C3FF4C21D25495
S2140028B000200800C0220000A80002C3C3A40048ED
S2140028C0B3FFFF6F0002A8000015C00087000005D8
S2140028D07C01C3FF4C21D25800200800C022000013
S2140028E0A80002B9C2B40004928002AE0418000A1E
S2140028F0A29802AC669800027C01C3FF4C21D27CF1
S21400290000380800C0380000AF00000004180002BD
S2140029108AD800057C01C3FF4C21D2600020080045
S214002920C0220000A80002A8041800019AD80005DA
S2140029307C01C3FF4C21D26400200800C0220000A6
S214002940A80002A10418000286D80009C3A4004CFF
S21400295007A50038B3FFFF97844000067C01C3FF3D
S2140029604C21D26C00200800C0220000A80002966D
S214002970D7A00038D2B800086718001AC3AF0038CE
S2140029807C0103FF4C21FFFF41E178004B0FC000A4
S214002990D7B80044A8000288041800038AD80005A7
S2140029A07C01C3FF4C21D26000200800C02200003A
S2140029B0A8000285041800039AD800057C01C3FF0E
S2140029C04C21D26400200800C0220000A800027E2D
S2140029D0C3A4004C07A5003CB3FFFF548440000589
S2140029E07C01C3FF4C21D26800200800C0220000F2
S2140029F0A8000275C3A4005007A50038B3FFFF6DFA
S214002A00844000057C01C3FF4C21D26C00200800E6
S214002A10C0220000A800026CC3B800387C01000188
S214002A2000017800970F00057C01C3FF4C21D2708F
S214002A3000200800C0220000A8000263D2B80008E8
S214002A406718001AC3AF003C65EF00104B0FC000BC
S214002A50C3AF003845EFFFFF4B0FC000D7B80044A8
S214002A60A8000255041800038AD800057C01C3FF9D
S214002A704C21D26000200800C0220000A8000252AC
S214002A80041800039AD800057C01C3FF4C21D264C9
S214002A9000200800C0220000A800024BC3A4004C7F
S214002AA007A5003CB3FFFF21844000057C01C3FF5F
S214002AB04C21D26800200800C0220000A800024274
S214002AC0C3A4005007A50038B3FFFF3A84400005B2
S214002AD07C01C3FF4C21D26C00200800C0220000FD
S214002AE0A8000239C3B800386F180010D7B80038ED
S214002AF0C3B800387C01000100017800970F00057C
S214002B007C01C3FF4C21D27000200800C0220000C8
S214002B10A800022DD2B800086718001AC3AF003C00
S214002B2065EF00104B0FC000C3AF003845EFFFFF46
S214002B304B0FC000D7B80044A800021F04180004BA
S214002B408AD800057C01C3FF4C21D2600020080013
S214002B50C0220000A800021C041800049AD8000531
S214002B607C01C3FF4C21D26400200800C022000074
S214002B70A8000215C3A4004C07A5003CB3FFFEEB5B
S214002B80844000057C01C3FF4C21D2680020080069
S214002B90C0220000A800020CC3A4005007A5003401
S214002BA0B3FFFEE2844000057C01C3FF4C21D268DF
S214002BB000200800C0220000A8000203C3A400549E
S214002BC007A50038B3FFFEFB844000057C01C3FF69
S214002BD04C21D26C00200800C0220000A80001FA98
S214002BE0C3B800387C01000100017800970F00058B
S214002BF07C01C3FF4C21D27000200800C0220000D8
S214002C00A80001F1D2B800086718001AC3AF003454
S214002C1065EF00154B0FC000C3AF003C65EF00101A
S214002C204B0FC000C3AF003845EFFFFF4B0FC0008F
S214002C30D7B80044A80001E0041800048AD80005AC
S214002C407C01C3FF4C21D26000200800C022000097
S214002C50A80001DD041800049AD800057C01C3FF13
S214002C604C21D26400200800C0220000A80001D633
S214002C70C3A4004C07A5003CB3FFFEAC844000058F
S214002C807C01C3FF4C21D26800200800C02200004F
S214002C90A80001CDC3A4005007A50034B3FFFEA3CF
S214002CA0844000057C01C3FF4C21D2680020080048
S214002CB0C0220000A80001C4C3A4005407A5004019
S214002CC0B3FFFEBC844000057C01C3FF4C21D26CE0
S214002CD000200800C0220000A80001BBC3B80040C6
S214002CE07C0100004C218000000178009B0F000250
S214002CF0040F80009B0F00057C01C3FF4C21D2709F
S214002D0000200800C0220000A80001AFD2B80008CA
S214002D106718001AC3AF003465EF00154B0FC000EC
S214002D20C3AF003C65EF00104B0FC000C3AF0040C0
S214002D3045EFFFFF4B0FC000D7B80044A800019E28
S214002D40041800048AD800057C01C3FF4C21D26019
S214002D5000200800C0220000A800019B0418000400
S214002D609AD800057C01C3FF4C21D26400200800DD
S214002D70C0220000A8000194C3A4004C07A5003C94
S214002D80B3FFFE6A844000057C01C3FF4C21D26875
S214002D9000200800C0220000A800018BC3A4005039
S214002DA007A50034B3FFFE61844000057C01C3FF25
S214002DB04C21D26800200800C0220000A800018232
S214002DC0C3A4005407A50030B3FFFE588440000596
S214002DD07C01C3FF4C21D26800200800C0220000FE
S214002DE0A8000179D2B800086718001AC3AF0034EB
S214002DF065EF00154B0FC000C3AF003065EF001045
S214002E004B0FC000C3AF003C65EF000B4B0FC0007C
S214002E10D7B80044A8000168041800048AD8000542
S214002E207C01C3FF4C21D26000200800C0220000B5
S214002E30A8000165041800049AD800057C01C3FFA9
S214002E404C21D26400200800C0220000A800015EC9
S214002E50C3A4004C07A5003CB3FFFE348440000525
S214002E607C01C3FF4C21D26800200800C02200006D
S214002E70A8000155C3A4005007A50034B3FFFE2BDD
S214002E80844000057C01C3FF4C21D2680020080066
S214002E90C0220000A800014CC3B80054CF180000A0
S214002EA0040F0024870F0016C3A4005407A50030A3
S214002EB0B3FFFE1E844000057C01C3FF4C21D26890
S214002EC000200800C0220000A800013FD2B8000879
S214002ED06718001AC3AF003465EF00154B0FC0002B
S214002EE0C3AF003065EF00104B0FC000C3AF003C0F
S214002EF065EF000B4B0FC000D7B80044A800012EAA
S214002F00C3A4005407A50038B3FFFE2A844000057A
S214002F107C01C3FF4C21D26C00200800C0220000B8
S214002F20A8000129C3B800387C0100010001780020
S214002F30970F00057C01C3FF4C21D27000200800CB
S214002F40C0220000A8000120D2B80008071800011F
S214002F506718001AC3AF003465EF00154B0FC000AA
S214002F60C3AF003C65EF00104B0FC000C3AF003886
S214002F7045EFFFFF4B0FC000D7B80044A800010E76
S214002F80041800048AD800057C01C3FF4C21D260D7
S214002F9000200800C0220000A800010B041800044E
S214002FA09AD800057C01C3FF4C21D264002008009B
S214002FB0C0220000A8000104C3A4004C07A5003CE2
S214002FC0B3FFFDDA844000057C01C3FF4C21D268C4
S214002FD000200800C0220000A80000FBC3A4005088
S214002FE007A50034B3FFFDD1844000057C01C3FF74
S214002FF04C21D26800200800C0220000A80000F281
S214003000C3B80054CF180000040F0024870F001622
S214003010C3A4005407A50030B3FFFDC484400005D8
S2140030207C01C3FF4C21D26800200800C0220000AB
S214003030A80000E5D2B800086718001AC3AF00342D
S21400304065EF00154B0FC000C3AF003065EF0010F2
S2140030504B0FC000C3AF003C65EF000B4B0FC0002A
S214003060D7B80044A80000D4C3A4005407A5004065
S214003070B3FFFDD0844000057C01C3FF4C21D26C19
S21400308000200800C0220000A80000CFC3B80040FF
S2140030907C0100004C218000000178009B0F00029C
S2140030A0040F80009B0F00057C01C3FF4C21D270EB
S2140030B000200800C0220000A80000C3D2B8000804
S2140030C0071800016718001AC3AF003465EF001533
S2140030D04B0FC000C3AF003C65EF00104B0FC000A5
S2140030E0C3AF004045EFFFFF4B0FC000D7B800440A
S2140030F0A80000B1041800048AD800057C01C3FFAC
S2140031004C21D26000200800C0220000A80000AEBB
S214003110041800049AD800057C01C3FF4C21D26431
S21400312000200800C0220000A80000A7C3A4004C8E
S21400313007A5003CB3FFFD7D844000057C01C3FF6E
S2140031404C21D26800200800C0220000A800009E83
S214003150C3A4005007A50034B3FFFD7484400005E7
S2140031607C01C3FF4C21D26800200800C02200006A
S214003170A8000095C3A4005407A50040B3FFFD8D2A
S214003180844000057C01C3FF4C21D26C002008005F
S214003190C0220000A800008CC3B8004047180003F7
S2140031A0830000057C01C3FF4C21D2740020080078
S2140031B0C0220000A8000084C3B80040C3AF00745B
S2140031C005EF00040B0FC000D7B80040C3B800409E
S2140031D027180004D7B80040C3B800407C010000A0
S2140031E04C218000000178009B0F0002040F800035
S2140031F09B0F00057C01C3FF4C21D27800200800FD
S214003200C0220000A8000070D2B800086718001A94
S214003210C3AF003C65EF00154B0FC000C3AF0034D2
S21400322065EF00104B0FC000C3AF004045EFFFFF37
S2140032304B0FC000D7B80044A800005F0418000277
S2140032408AD800057C01C3FF4C21D260002008000C
S214003250C0220000A800005C041800029AD80005EE
S2140032607C01C3FF4C21D26400200800C02200006D
S214003270A8000055C3A4004C07A50040B3FFFD4DB1
S214003280844000057C01C3FF4C21D26C002008005E
S214003290C0220000A800004CC3B800404718000336
S2140032A0830000057C01C3FF4C21D2740020080077
S2140032B0C0220000A8000044C3B80040C3AF00749A
S2140032C005EF00040B0FC000D7B80040C3B800409D
S2140032D027180004D7B80040C3B800407C0102009D
S2140032E0000178009B0F00037C01FE0000017800BF
S2140032F09B0F00057C01C3FF4C21D27800200800FC
S214003300C0220000A8000030D2B800086718001AD3
S214003310C3AF00407C0103FF4C21FFFF41E1780072
S2140033204B0FC000D7B80044A800002304180002C2
S2140033308AD800057C01C3FF4C21D260002008001B
S214003340C0220000A8000020041800029AD8000539
S2140033507C01C3FF4C21D26400200800C02200007C
S214003360A8000019C3A4004C07A5003CB3FFFCEF5F
S214003370844000057C01C3FF4C21D2680020080071
S214003380C0220000A8000010D2B800086718001A73
S214003390C3AF003C65EF00154B0FC000D7B8004424
S2140033A0A80000057C01C3FF4C21D25C0020080069
S2140033B0C0220000A8000004C3B80078C3AF0044D1
S2140033C0D70F000000001000C3B40010C3B50014EF
S2140033D0C3B60018C3B7001CC3BF002007BD0070EB
S2140033E0AFE000000FBD0020D7BF0010D7A400201C
S2140033F0D7A50024C3B80024870000097C01C3FFBA
S2140034004C21DC14000120007C01C3FF4C21D47049
S21400341000012800C3A60020B0000CF2A800000996
S2140034207C01C3FF4C21DC14000120007C01C3FF9B
S2140034304C21D46600012800C3A60020C3A70024A0
S214003440B0000CE8C3BF001007BD0020AFE00000CE
S2140034500FBD0020D7BF0014D7A40020D7A5002496
S214003460D7A60028C3B80028DBB800287C01C3FF15
S2140034704C21DC14000120007C01C3FF4C21D458F1
S21400348000012800C3A60020C3A70024CBB800284C
S214003490D7B80010B0000CD3C3BF001407BD00207F
S2140034A0AFE000000FBD0020D7BF0014D7A4002057
S2140034B0D7A50024D7A60028C3B80028DBB8002864
S2140034C07C01C3FF4C21DC14000120007C01C3FFFB
S2140034D04C21D44A00012800C3A60020C3A700241C
S2140034E0CBB8002867180010D7B80010B0000CBD85
S2140034F0C3BF001407BD0020AFE000000FBD0020D2
S214003500D7BF0018D7A40020D7A50024D7A6002828
S214003510D7A7002CC3B8002CDBB8002C7C01C3FF57
S2140035204C21DC14000120007C01C3FF4C21D43860
S21400353000012800C3A60020C3A70024C3B80028A3
S214003540D7B80010CBB8002CD7B80014B0000CA524
S214003550C3BF001807BD0020AFE000000FBD00404D
S214003560D7B3001CD7B40020D7B50024D7B60028A0
S214003570D7B7002CD7BF0030D7A40040D7A500444B
S214003580D7A600480007B8007C01C3FF4C21DC1416
S214003590000120007C01C3FF4C21D4240001280038
S2140035A0C3A60040C3A70044C3B80048D7B800105D
S2140035B046F8FFFF47188000830000047C01C3FF25
S2140035C04C21D4220001B000A80000037C01C3FFF8
S2140035D04C21D4200001B000D7B6001446F8FFFFF7
S2140035E0471880008300000D46F8FFFF471880004C
S2140035F08300000446F8FFFF7C01FFFF4B01A0009C
S214003600A800000246F8FFFF4714FFFF0014C000A2
S2140036100818C0000018A800A800000A46F8FFFF17
S214003620471880008300000446F8FFFF7C01FFFF78
S2140036304B019800A800000246F8FFFF4713FFFF63
S2140036400013A800D7B50018B0000C66C3B3001C62
S214003650C3B40020C3B50024C3B60028C3B7002CEB
S214003660C3BF003007BD0040AFE000000FBD002024
S214003670D7BF0018D7A40020D7A50024D7A60028B7
S214003680D7A7002C7C01C3FF4C21DC1400012000CE
S2140036907C01C3FF4C21D40F00012800C3A60020E4
S2140036A0C3A70024C3B80028D7B80010C3B8002C9E
S2140036B0D7B80014B0000C4BC3BF001807BD0020DD
S2140036C0AFE000000FBD0030D7B60018D7B7001C1B
S2140036D0D7BF0020D7A40030D7A50034D7A600381F
S2140036E00007B8007C01C3FF4C21DC140001200059
S2140036F07C01C3FF4C21D3FD00012800C3A6003087
S214003700C3A70034C3B80038D7B8001046F8FFFF88
S214003710471880008300000446F8FFFF7C01FFFF87
S2140037204B01B000A800000246F8FFFF4716FFFF57
S214003730C3B800400718000466CF0002030FC0009D
S214003740D7B80014B0000C27C3B60018C3B7001CC7
S214003750C3BF002007BD0030AFE000000FBD002053
S214003760D7B60010D7B70014D7BF0018D7A40020CC
S2140037700005B800D7A600287C01C3FF4C21DC1446
S214003780000120007C01C3FF4C21D4660001280004
S214003790C3A600207C01020042E1C00083000003B3
S2140037A07C01FC004AE1B000A80000037C0103FF96
S2140037B04C21FFFF42E1B000C3B800280718000400
S2140037C066CF0002030F3800B0000C06C3B6001028
S2140037D0C3B70014C3BF001807BD0020AFE0000049
S2140037E00FBD0020D7BF0010D7A40020D7A5002407
S2140037F07C01C3FF4C21DC14000120007C01C3FFC8
S2140038004C21D3F400012800C3A60020C3A700243F
S214003810B0000BF4C3BF001007BD0020AFE00000EF
S2140038200FBD0030D7B60014D7B70018D7BF001C9E
S214003830D7A40030D7A50034C3B800306F18001ADC
S2140038404718003FDFB8002FD3B8002F67180002D4
S2140038507C01C3FF4C21DB0C00380800C037000099
S2140038600017C000870000067C01C3FF4C21D3F080
S2140038700001200000002800B3FFFEDAA80000A127
S214003880C2F6000492C0009B0418000AA2D8009951
S21400389066D800027C01C3FF4C21D3A00038080084
S2140038A0C0380000AF000000C2E40000C3B800301B
S2140038B07C0103FF4C21FFFF43012800B3FFFEC934
S2140038C0A8000090C2E40000C3B800306F0F0010DC
S2140038D045EF001F000F28004718FFFF4706FFFFB1
S2140038E0B3FFFEDBA8000087C2E40000C3B80030C8
S2140038F06F0F001045EF001F000F28004718FFFF4E
S2140039004706FFFFB3FFFEE7A800007EC2E4000004
S214003910C3B800306F0F001045EF001F000F2800DF
S2140039206F0F001545EF001F000F30004718FFFF10
S2140039304707FFFFB3FFFEF1A8000072C2E40000D5
S214003940C3B800306F0F001045EF001F000F2800AF
S2140039506F0F001545EF001F000F30004718FFFFE0
S2140039604707FFFFB3FFFEFDA8000066C2E40000A5
S214003970C3B800306F0F000B45EF001F000F280084
S2140039806F0F001545EF001F000F30006F18001076
S2140039904718001F00183800B3FFFF34A80000596E
S2140039A0D3B8002F471800018700000DC2E40000BE
S2140039B0C3B800306F0F000B45EF001F000F280044
S2140039C06F0F001545EF001F000F30006F18001036
S2140039D04718001F00183800B3FFFF24A80000494E
S2140039E0C2E40000C3B800306F0F001045EF001FA0
S2140039F0000F28006F0F001545EF001F000F300066
S214003A004718FFFF4707FFFFB3FFFEBCA800003DB7
S214003A10D3B8002F471800018700000DC2E400004D
S214003A20C3B800306F0F000B45EF001F000F2800D3
S214003A306F0F001545EF001F000F30006F180010C5
S214003A404718001F00183800B3FFFF08A800002D15
S214003A50C2E40000C3B800306F0F001045EF001F2F
S214003A60000F28006F0F001545EF001F000F3000F5
S214003A704718FFFF4707FFFFB3FFFEB8A800002167
S214003A80C2E40000C3B800306F0F001545EF001FFA
S214003A90000F28006F0F001045EF001F000F3000CA
S214003AA04718FFFF4707FFFFC3B80034D7B800101A
S214003AB0B3FFFF04A8000013C2E40000C3B8003040
S214003AC07C0103FF4C21FFFF43012800C3A60034FE
S214003AD0B3FFFF22A800000BC2E40000C3B800300A
S214003AE06F1800154718001F00182800B3FFFF3C8A
S214003AF0A80000047C01C3FF4C21D3CC00012000A9
S214003B00B0000B0F7C01C3FF4C21DC140001100039
S214003B10C3B60014C3B70018C3BF001C07BD0030EF
S214003B20AFE000000FBD0010D7B60000D7B7000406
S214003B307C01C3FF4C21DC7C00240800D038000048
S214003B400018B8000418003096F80004041800396D
S214003B50A6F800020EF70030A800000E0418004178
S214003B6096F8000404180046A6F800020EF7003780
S214003B70A80000080418006196F8000404180066FF
S214003B80A6F800020EF70057A80000020402FFFF86
S214003B90A800001B7C01C3FF4C21DC7D002408002C
S214003BA0D03800000018B0000418003096D8000482
S214003BB004180039A6D800020ED60030A800000E61
S214003BC00418004196D8000404180046A6D800023F
S214003BD00ED60037A80000080418006196D8000426
S214003BE004180066A6D800020ED60057A8000002E9
S214003BF00402FFFFA800000266F800044B1610003F
S214003C00C3B60000C3B7000407BD0010AFE0000055
S214003C100FBD0020D7BF0010D7A40020D7A50024D2
S214003C20C3B8002087000004C3B800240018200092
S214003C30B0000CA5A8000003C3B80024001820009C
S214003C40B0000CBCC3BF001007BD0020AFE00000F2
S214003C500FBD0020D7BF0010D7A40020C3B8002097
S214003C6087000003B0000C870002C000A800000216
S214003C70B0000C9C0002C000C3BF001007BD0020AF
S214003C80AFE000000FBD0020D7BF0010D7A4002073
S214003C90C3B8002087000003B0000C7F0002C000FD
S214003CA0A8000002B0000C950002C000C3BF0010C0
S214003CB007BD0020AFE000000FBD0070D7B00010B9
S214003CC0D7B10014D7B20018D7B3001CD7B4002061
S214003CD0D7B50024D7B60028D7B7002CD7BF0030FA
S214003CE00004B8007C01C3FF4C21D5E00001200091
S214003CF0B0000A930000A800001720000405007317
S214003D00B3FFFFC30000B00000172000B3FFFFD0D2
S214003D1080400001A800000506D600017C010005D1
S214003D204C2157300001C00092D8FFF77C010005F7
S214003D304C2157300001C0009AD80001A8000007A7
S214003D407C01C3FF4C21D5CA00012000B0000A7CCC
S214003D5006B500010418000A92B8FFE70418000A26
S214003D6082B8000400172000B3FFFFC6040F0061EE
S214003D70804F00057C01C3FF4C21D59A000120002E
S214003D80B0000A6FA800011A0017200004050061A1
S214003D90B3FFFF9F7C01C3FF4C21D57F00012000AD
S214003DA0B0000A6704180001D7B8006CA800010725
S214003DB00017200004050072B3FFFF950000A8005E
S214003DC000172000B3FFFFAF0002C0007C01C3FF56
S214003DD04C21DC7C00350800DC3800007C01C3FF89
S214003DE04C21DC7C00350800D0380000040F000AA7
S214003DF0870F0001A800000306B50001041802089A
S214003E0092B8FFEF0418020886B800057C01C3FFCD
S214003E104C21D55600012000B0000A49A80000ED4C
S214003E207C01C3FF4C21DC7C00350800DC20000050
S214003E307C01C3FF4C21D552000120007C01C3FF4A
S214003E404C21DC7C00012800B0000A3D7C01C3FF49
S214003E504C21DC7C00200800D0380000040F005302
S214003E60830F00057C01C3FF4C21D53600012000DE
S214003E70B0000A33A80000D77C01C3FF4C21DC7DCC
S214003E8000200800D030000004040002B3FFFF2525
S214003E9000029000665800010718000482B800056A
S214003EA07C01C3FF4C21D50900012000B0000A2484
S214003EB0A80000C80000A00004160002A800000425
S214003EC000162000B3FFFF170282A00006D60002ED
S214003ED092D5FFFB041800FF468F00FF81F800050F
S214003EE07C01C3FF4C21D4E500012000B0000A1479
S214003EF0A80000B804180030921800AF0418003963
S214003F00A21800AD661800027C01C3FF4C21D3B88E
S214003F1000380800C0380000AF00000004040004A9
S214003F20B3FFFF000002C000D7B800680404000614
S214003F30B3FFFEFCC3AF006865EF000849E28800E7
S214003F407C01C0004A2188000000B000A8000009DB
S214003F5066D8000107040008B3FFFEF200029800CE
S214003F600016C00002382000466500FFB00003D3EC
S214003F7006D600010E58000392D8FFF5A80000935D
S214003F8004040004B3FFFEE70002C000D7B80064D4
S214003F9004040006B3FFFEE30002C000D7B80060CA
S214003FA0040F0008000F2000B3FFFEDEC3AF00645E
S214003FB065EF0010C3AE006065CE000849EE7800DD
S214003FC049E288007C01C0004A2188000000B00059
S214003FD0A800000966D800010704000AB3FFFED156
S214003FE0000298000016C00002382000466500FF58
S214003FF0B00003B206D600010E58000492D8FFF5B2
S214004000A800007204040004B3FFFEC60002C0004D
S214004010D7B8005C04040006B3FFFEC20002C0006E
S214004020D7B8005804040008B3FFFEBE0002C00064
S214004030D7B800540404000AB3FFFEBAC3AF005C4E
S21400404065EF0018C3AE005865CE001A49EE78003A
S214004050C3AE005465CE000849EE780049E28800F9
S2140040607C01C0004A2188000000B000A8000009BA
S21400407066D800010704000CB3FFFEAA00029800F1
S2140040800016C00002382000466500FFB000038B13
S21400409006D600010E58000592D8FFF5A800004B82
S2140040A004040004B3FFFE9F0002C000D7B800500F
S2140040B004040006B3FFFE9B0002C000D7B8004C05
S2140040C004040008B3FFFE970002C000D7B80048FB
S2140040D00404000AB3FFFE930002C000C3AF005002
S2140040E065EF0018C3AE004C65CE001A49EE7800A6
S2140040F0C3AE004865CE000849EE780049F888004F
S2140041007C01C0004A21880000112000B000009603
S214004110D7A0006CA800002D04040004B3FFFE81A5
S2140041200002C000D7B8004404040006B3FFFE7DBA
S2140041300002C000D7B80040040F0008000F20009F
S214004140B3FFFE780002C000C3AF004465EF001066
S214004150C3AE004065CE000849EE780049F88800F6
S2140041607C01C0004A21880000112000B000007EBB
S214004170D7A0006CA800001504040004B3FFFE6975
S2140041800002C000D7B8003C04040006B3FFFE657A
S2140041900002C000C3AF003C65EF000849F8880085
S2140041A07C01C0004A21880000112000B000006E8B
S2140041B0D7A0006CA80000057C01C3FF4C21D4C327
S2140041C000012000B000095ED7A0006CC3B8006CE8
S2140041D08700FEF70017200004050071B3FFFE8C71
S2140041E07C01C3FF4C21D4A000012000B00009547C
S2140041F0C3B00010C3B10014C3B20018C3B3001C90
S214004200C3B40020C3B50024C3B60028C3B7002C2F
S214004210C3BF003007BD0070AFE000000FBD003028
S214004220D7B60014D7B70018D7BF001C0004B800D4
S21400423000172000B3FFEF7D0002B00086C0000527
S2140042407C01C3FF4C21D65900012000B000093C78
S214004250A800003B7C01C3FF4C21D62D00012000A6
S21400426000162800B000093600172000040500726A
S214004270000030000000380004180001D7B8001015
S214004280B3FFEF6B804000057C01C3FF4C21D620B6
S21400429000012000B000092AA80000297C01C00007
S2140042A04C2101FE00012000B00002FB0002C0000D
S2140042B0DFB8002F7C01C0004C2101FF0001200068
S2140042C0B00002F50002C000DFB8002ED3B8002F01
S2140042D0040F0055870F0003D3B8002E040F00AA62
S2140042E0830F00057C01C3FF4C21D6080001200087
S2140042F0B0000913A80000120404001000172800DC
S214004300B00000250404001100002800B0000022C0
S2140043100404001200162800B000001F0404001D4C
S2140043207C01C0004C21100000012800B000001ADB
S2140043307C01C00000012000B000000BB00001DAD4
S214004340C3B60014C3B70018C3BF001C07BD0030B7
S214004350AFE000007C01C3FF4C21DF1800200800FE
S214004360C0220000AFE000007C01C3FF4C21DF1834
S21400437000200800D4240000AFE000004498001F8E
S214004380671800027C01C3FF4C21DE940038080049
S214004390C0220000AFE000004498001F8300000722
S2140043A04498001F671800027C01C3FF4C21DE946E
S2140043B000380800D4250000A8000000AFE0000088
S2140043C07C01C3FF4C21DF1400200800C02200003F
S2140043D0AFE000007C01C3FF4C21DF140020080082
S2140043E0D4240000AFE000007C01C3FF4C21DE9027
S2140043F000200800C0220000AFE000007C01C3FFE0
S2140044004C21DE8C00200800C0220000AFE0000037
S2140044107C01C3FF4C21DE8C00200800D424000061
S214004420041800017C01C3FF4C21DE900020080028
S214004430D4380000AFE000007C01C3FF4C21DE90C2
S21400444000200800D4200000AFE0000090800003A9
S2140044500004C000040F0020970F00047C01C3FF77
S2140044604C21D7D100011000A80000056498000276
S2140044707C01C3FF4C21D66C00380800C022000027
S214004480AFE000000FBD0020D7BF0010D7A400206B
S214004490D7A50024D7A60028C3B800209300003A6A
S2140044A0040F0009A30F0038671800027C01C3FF41
S2140044B04C21D72C00380800C0380000AF000000A0
S2140044C0C3B80024C3AF0028870F003404020001DD
S2140044D0A8000033C3B80024C3AF0028830F002F02
S2140044E004020001A800002EC3B80024C3AF0028B1
S2140044F0A30F002A04020001A8000029C3B8002464
S214004500C3AF0028A70F002504020001A80000245E
S214004510C3B80024C3AF00289B0F0020040200018C
S214004520A800001FC3B80024C3AF00289F0F001BBD
S21400453004020001A800001AC3B80024C3AF002874
S214004540930F001604020001A8000015C3B800244B
S214004550C3AF0028970F001104020001A800001046
S214004560C3B80024C3AF00288B0F000C0402000160
S214004570A800000BC3B80024C3AF00288F0F0007A5
S21400458004020001A80000067C01C3FF4C21D7AF3F
S21400459000012000C3A50020B0000869000010003C
S2140045A0C3BF001007BD0020AFE000000FBD0070C5
S2140045B0D7B30010D7B40014D7B50018D7B6001C70
S2140045C0D7B70020D7BF00247C01C3FF4C21DF18DB
S2140045D000200800C0240000B00002290002B0003D
S2140045E06ED8001A4718003FD7B8006C6ED8001572
S2140045F04718001FD7B800306ED800104718001FA5
S214004600D7B8002846D8FFFFDBB8002E7C0103FF92
S2140046104C21FFFF42C1C000D7B800340418000187
S214004620D7B80068C3B8006C7C01C3FF4C21D6EC39
S21400463000380800D0340000041800019298004AA0
S21400464004180004A2980048669800027C01C3FF84
S2140046504C21D75000380800C0380000AF000000DA
S2140046607C01C3FF4C21DF1800200800C038000082
S21400467007150004A80000427C01C3FF4C21DF1888
S21400468000200800C038000007150004C3B8006CFE
S2140046900F040020C3B80030671800027C01C3FF77
S2140046A04C21DE9400380800C0250000C3B800285E
S2140046B0671800027C01C3FF4C21DE940038080016
S2140046C0C0260000B3FFFF6F8040002DCBB8002E41
S2140046D04718800083000004CBB8002E7C01FFFF43
S2140046E04B019800A8000002CBB8002E4713FFFF2E
S2140046F06678000202B8A800A8000021C3B80034FB
S2140047007C0102004301C00083000004C3B80034EB
S2140047107C01FC004B019800A8000004C3B80034DC
S2140047207C0103FF4C21FFFF430198007C01C3FF7F
S2140047304C21DF1800200800C038000007180004CD
S214004740666F0002030FA800A800000DC3B8003073
S214004750671800027C01C3FF4C21DE940038080075
S214004760C0350000A80000067C01C3FF4C21D77CA2
S21400477000012000C3A5006CB00007F1D7A00068B8
S214004780C3B800688700000200001000A80000BE42
S21400479000152000B00001BAD7A200640015200062
S2140047A00418002E6718001A00182800B00001BD73
S2140047B00000B80066F800027C01C3FF4C21DE94BE
S2140047C000380800C02F00007C01C3FF4C21DA74BB
S2140047D000380800D42F000006F700010418002057
S2140047E092F8FFF47C01C3FF4C21DF18002008007C
S2140047F0C03800007C01C3FF4C21DAEC0020080022
S214004800D43800007C01C3FF4C21DF1400200800D0
S214004810C03800007C01F7FF4C21FFFF4301C000B9
S2140048207C01C3FF4C21DAF400200800D4380000D5
S214004830B00001A57C01C3FF4C21DAF80020080077
S214004840D4220000B00001AA7C01C3FF4C21DAFC90
S21400485000200800D4220000B00001AF7C01C3FF96
S2140048604C21DB0000200800D422000007A4003CF6
S214004870B3FFEE388040000B7C01C3FF4C21DA709A
S21400488000200800C0380000D7B8003807B8003C41
S2140048907C01C3FF4C21DA7000200800D4380000E9
S2140048A0B3FFEE49C3B800387C01C3FF4C21DA7071
S2140048B000200800D43800000000B80082E0000A9B
S2140048C066F800027C01C3FF4C21DA740038080049
S2140048D0C02F00007C01C3FF4C21DE940038080086
S2140048E0D42F0000A800000006F7000104180020DE
S2140048F092F8FFF27C01C3FF4C21DAEC002008009E
S214004900C03800007C01C3FF4C21DF1800200800DF
S214004910D43800007C01C3FF4C21DAF400200800E4
S214004920C03800007C01C3FF4C21DF1400200800C3
S214004930C02F00007C01080041E178004B0FC0004A
S2140049407C01C3FF4C21DF1400200800D43800008F
S2140049507C01C3FF4C21DAF800200800C0240000C8
S214004960B000015E7C01C3FF4C21DAFC0020080089
S214004970C0240000B00001637C01C3FF4C21DB00B3
S21400498000200800C0240000B000016800152000C8
S214004990C3A50064B00001437C01C3FF4C21DF18AF
S2140049A000200800C038000086B80002040200019B
S2140049B0A80000357C01C3FF4C21DF14002008004E
S2140049C0C03800007C0108004301C00087000011C9
S2140049D07C01C3FF4C21DF1400200800C038000013
S2140049E07C01001F4301C0006F1800100018200053
S2140049F0B3FFFE960002C0007C01C3FF4C21D764C3
S214004A000001200000182800B000074D000010002C
S214004A10A800001D7C01C3FF4C21DF140020080005
S214004A20C03800007C01001F4301C0006F18001052
S214004A30040F0015870F000CB000012D7C018000CC
S214004A404041C000870000087C01C0004C210008DF
S214004A500001C0007C01C3FF4C21DF1800200800C5
S214004A60D4380000A80000077C01C0004C210004D8
S214004A700001C0007C01C3FF4C21DF1800200800A5
S214004A80D438000004020001C3B30010C3B40014FD
S214004A90C3B50018C3B6001CC3B70020C3BF0024AC
S214004AA007BD0070AFE000000FBD0050D7B5001086
S214004AB0D7B60014D7B70018D7BF001C7C01C3FFB9
S214004AC04C21DE9000200800C0380000830000E47F
S214004AD07C01C3FF4C21DE8C00200800C03800009B
S214004AE07C01C3FF4C21DF1800200800C02F000007
S214004AF0870F00DBB3FFFEAD844000D90000100036
S214004B00A80000D97C01C3FF4C21DE9000200800DD
S214004B10C03800008300000E7C01C3FF4C21DE8CF1
S214004B2000200800C0240000B00000D50002A80045
S214004B307C01C3FF4C21DE8C00200800C02400004E
S214004B400418002E6718001A00182800B00000D5B8
S214004B500000B80066F800027C01C3FF4C21DE941A
S214004B6000380800C02F00007C01C3FF4C21DA7417
S214004B7000380800D42F000006F7000104180020B3
S214004B8092F8FFF47C01C3FF4C21DF1800200800D8
S214004B90C03800007C01C3FF4C21DAEC002008007E
S214004BA0D43800007C01C3FF4C21DF14002008002D
S214004BB0C03800007C01F7FF4C21FFFF4301C00016
S214004BC07C01C3FF4C21DAF400200800D438000032
S214004BD0B00000BD7C01C3FF4C21DAF800200800BD
S214004BE0D4220000B00000C27C01C3FF4C21DAFCD6
S214004BF000200800D4220000B00000C77C01C3FFDC
S214004C004C21DB0000200800D422000007A4002866
S214004C10B3FFED508040000A7C01C3FF4C21DA70E0
S214004C2000200800C036000007B800287C01C3FF3B
S214004C304C21DA7000200800D4380000B3FFED6283
S214004C407C01C3FF4C21DA7000200800D436000037
S214004C500000B80082E0000A66F800027C01C3FF8C
S214004C604C21DA7400380800C02F00007C01C3FF16
S214004C704C21DE9400380800D42F0000A800000065
S214004C8006F700010418002092F8FFF27C01C3FF2B
S214004C904C21DAEC00200800C03800007C01C3FF7D
S214004CA04C21DF1800200800D43800007C01C3FF28
S214004CB04C21DAF400200800C03800007C01C3FF55
S214004CC04C21DF1400200800C02F00007C010800E3
S214004CD041E178004B0FC0007C01C3FF4C21DF147C
S214004CE000200800D43800007C01C3FF4C21DAF80D
S214004CF000200800C0240000B00000787C01C3FF3C
S214004D004C21DAFC00200800C0240000B000007D22
S214004D107C01C3FF4C21DB0000200800C0240000FB
S214004D20B00000827C01C3FF4C21DE90002008000A
S214004D30C0380000830000067C01C3FF4C21DE8CD7
S214004D4000200800C024000000152800B000005510
S214004D507C01C3FF4C21DE9000200800C038000014
S214004D608300000B7C01C3FF4C21DE8C0020080072
S214004D70C03800007C01C3FF4C21DF18002008006B
S214004D80C02F0000870F000204020001A8000036B2
S214004D907C01C3FF4C21DF1400200800C03800004F
S214004DA07C0108004301C000870000117C01C3FF9E
S214004DB04C21DF1400200800C03800007C01001FD2
S214004DC04301C0006F18001000182000B3FFFD9FBD
S214004DD00002C0007C01C3FF4C21D7640001200004
S214004DE000182800B000065600001000A800001E9C
S214004DF07C01C3FF4C21DF1400200800C0380000EF
S214004E007C01001F4301C0006F180010040F00153E
S214004E10870F000CB00000367C0180004041C000C7
S214004E20870000087C01C0004C2100080001C0007B
S214004E307C01C3FF4C21DF1800200800D438000096
S214004E40A80000077C01C0004C2100040001C0003F
S214004E507C01C3FF4C21DF1800200800D438000076
S214004E60ABFFFF2800001000C3B50010C3B6001447
S214004E70C3B70018C3BF001C07BD0050AFE000005A
S214004E800004C000C3020000AFE000000004C00041
S214004E90CB020000AFE000000004C000D302000018
S214004EA0AFE000000004C000D7050000AFE000003F
S214004EB00004C000DB050000AFE000000004C000F6
S214004EC0DF050000AFE000007C01C3FF4C21DF28B7
S214004ED000200800C0220000AFE000007C01C3FFF5
S214004EE04C21DF2800200800D4240000AFE000009A
S214004EF07C01C3FF4C21DF2400200800C0220000F4
S214004F00AFE000007C01C3FF4C21DF240020080036
S214004F10D4240000AFE000007C01C3FF4C21DF205A
S214004F2000200800C0220000AFE000007C01C3FFA4
S214004F304C21DF2000200800D4240000AFE0000051
S214004F400FBD0040D7B50010D7B60014D7B700186D
S214004F50D7BF001CD7A40040D7A50044C3A4004474
S214004F60B3FFEC61D7A2002CC3A40044B3FFEC62ED
S214004F700002B800C3B8002C7C01FFFF4C21F000F3
S214004F804301C000D7B800307C01FFFF4C21F00081
S214004F9042E1C000D7B8003446F8000283000002A1
S214004FA004160001A80000010000B000D7B60038C3
S214004FB046F800018300000204150001A800000165
S214004FC00000A800D7B5003CC3B8004007A80030D2
S214004FD0C1030000C1090004D7030000D70900047C
S214004FE0C1030008C109000CD7030008D709000C4C
S214004FF0C3B50010C3B60014C3B70018C3BF001C67
S21400500007BD0040AFE000000FBD0020D7B700107E
S214005010D7BF0014D7A40020D7A50024D7A6002801
S214005020D7A7002C0000B800C3B8002C83000001EE
S2140050304EF70002C3B80030830000014EF70001AF
S214005040C3A40020C3A50024C3B800284B17300013
S214005050B3FFEC2DC3B70010C3BF001407BD00207C
S214005060AFE000000FBD0030D7B20010D7B3001479
S214005070D7B40018D7B5001CD7B60020D7B7002481
S214005080D7BF00280004B80000172000B00005AC09
S214005090000098007C01C3FF4C21DF800020080040
S2140050A0C0340000A80000BEB00002C20002A80083
S2140050B066B20018765200180418000D8258000BCD
S2140050C00418000E8258006F041800108258001B47
S2140050D0A2580003041800088258000EA800009B7F
S2140050E00418007F8258000BA80000980404000AE9
S2140050F0B00002B97C01C3FF4C21DF30003308004A
S214005100DC2000007C01C3FF4C21DF3000011000D2
S214005110A80000A586600001A80000A104040008FD
S214005120B00002AD04040020B00002AB0404000886
S214005130B00002A90E730001A80000997C01C3FF0D
S2140051404C21DF8000200800C0380000869800113F
S2140051507C01C3FF4C21DF3000330800DC20000058
S214005160041800507C01C3FF4C21DF80002008009B
S214005170C02F0000130FC0007C01C3FF4C21DF844A
S214005180030120007C01C3FF4C21DF300001280012
S214005190B00000E30E9600010418FFFF86D8000159
S2140051A0041600137C01C3FF4C21DF80002008009A
S2140051B0C038000086D8000304040007B00002864A
S2140051C0A8000077041800501316C0007C01C3FF27
S2140051D04C21DF8400380800CC380000870000032C
S2140051E004040007B000027CA800006D0016A000B2
S2140051F07C01C3FF4C21DF30000120000418005062
S2140052001314C0007C01C3FF4C21DF840301280077
S214005210B00000C37C01C3FF4C21D9CA00012000A6
S214005220B00005470000B0007C01C3FF4C21D9C880
S21400523000012000B000054206D600010418004F09
S21400524092D8FFF97C01C3FF4C21D9CA0001200087
S214005250B000053B00172000B00005397C01C3FFF5
S2140052604C21DF3000012000B00005357C01C3FF73
S2140052704C21DF3000012000B000008D00029800B5
S214005280A80000477C01C3FF4C21DF8000200800F7
S214005290C03800008698000304040007B000024EE1
S2140052A0A800003F069600010418001486D80001E6
S2140052B00000B0000016A0007C01C3FF4C21DF30C8
S2140052C000012000041800501314C0007C01C3FF26
S2140052D04C21DF8403012800B00000917C01C3FF4D
S2140052E04C21D9CA00012000B00005150000B0000E
S2140052F07C01C3FF4C21D9C800012000B000051076
S21400530006D600010418004F92D8FFF97C01C3FFAF
S2140053104C21D9CA00012000B00005090017200062
S214005320B00005077C01C3FF4C21DF3000012000E0
S214005330B00005037C01C3FF4C21DF3000012000D4
S214005340B000005B00029800A800001566B80018C0
S21400535077180018040F0009870F000104150020B5
S21400536066B8001877180018040F0020930F000284
S214005370040F007E8B0F0001A800000966A4001829
S21400538074840018B00002140013C0000713000154
S2140053907C01C3FF4C21DF3000380800DC350000FC
S2140053A0ABFFFF4100001000C3B20010C3B30014EF
S2140053B0C3B40018C3B5001CC3B60020C3B700248E
S2140053C0C3BF002807BD0030AFE000000FBD0020BF
S2140053D0D7B60010D7B70014D7BF00180004B8001F
S2140053E0CEF8000087000001A800002B7C01C3FF58
S2140053F04C21DF8000200800C03800000F16000196
S2140054000418FFFF86D80001041600130418005085
S2140054101316C0007C01C3FF4C21DF84030120006B
S21400542000172800B000003084400001A800001AD1
S214005430041800507C01C3FF4C21DF8000200800C8
S214005440C02F0000130FC0007C01C3FF4C21DF8477
S2140054500301200000172800B00000317C01C3FFC4
S2140054604C21DF8000200800C0380000071800012B
S2140054707C01C3FF4C21DF8000200800D4380000E8
S214005480040F0014870F00047C01C3FF4C21DF804B
S21400549000200800D4200000C3B60010C3B70014D4
S2140054A0C3BF001807BD0020AFE00000AFE000005B
S2140054B00FBD0010D7B700000004B800A800000118
S2140054C006F70001CEF800008700FFFD0017C000B9
S2140054D0000478000B0FC00000181000C3B70000CF
S2140054E007BD0010AFE00000A8000006CC98000042
S2140054F08700000200001000A800000804840001D5
S21400550004A50001CC980000CCAF0000830FFFF785
S214005510CC980000CCAF00000B0F1000AFE00000EE
S2140055200FBD0010D7B700000004B800A8000002A6
S21400553006F7000104A50001CCB80000DEF8000064
S21400554067180018771800188700FFF90004100085
S214005550C3B7000007BD0010AFE000000FBD00108D
S214005560D7B700000004B800A800000106F7000145
S214005570CEF800008700FFFDA800000206F7000135
S21400558004A50001CCB80000DEF80000671800187B
S214005590771800188700FFF900041000C3B7000052
S2140055A007BD0010AFE00000A8000005CC98000082
S2140055B08700000200001000A80000060484000116
S2140055C0CC98000064AF001875EF0018870FFFF73F
S2140055D000041000AFE000000FBD0020D7B7001099
S2140055E0D7BF0014D7A400200005B800C3B8002019
S2140055F083000006C3B800207C01C3FF4C21E5C829
S21400560000200800D4380000A80000137C01C3FF67
S2140056104C21E5C800200800C0380000071800012B
S2140056207C01C3FF4C21E5C800200800D4380000E8
S214005630A80000097C01C3FF4C21E5C80020080033
S214005640C0380000071800017C01C3FF4C21E5C8E4
S21400565000200800D43800007C01C3FF4C21E5C8B8
S21400566000200800C0380000CF18000083000005A6
S2140056700017200000182800B3FFFFCB0002C00070
S2140056808700FFEC7C01C3FF4C21E5C80020080022
S214005690C0380000CF18000087000002000010008D
S2140056A0A80000357C01C3FF4C21E5C80020080097
S2140056B0C0380000070F00017C01C3FF4C21E5C87D
S2140056C000200800D42F0000D7B8001CA80000094E
S2140056D07C01C3FF4C21E5C800200800C03800004C
S2140056E0071800017C01C3FF4C21E5C80020080014
S2140056F0D43800007C01C3FF4C21E5C80020080018
S214005700C0380000CF1800008300000500172000F6
S21400571000182800B3FFFFA40002C0008300FFECBF
S2140057207C01C3FF4C21E5C800200800C0380000FB
S214005730CF180000830000067C01C3FF4C21E5C89B
S21400574000200800C0380000DF000000A8000009A4
S2140057507C01C3FF4C21E5C800200800C0380000CB
S2140057600718FFFF7C01C3FF4C21E5C80020080096
S214005770D4380000C3A2001CC3B70010C3BF001477
S21400578007BD0020AFE000000FBD0010D7B7000037
S2140057906497001876F700180418000992F8000EAF
S2140057A00418000DA2F8000666F800027C01C3FF8C
S2140057B04C21D9A800380800C0380000AF0000000F
S2140057C00418002082F80001A80000030418000155
S2140057D0D7B8000CA8000001D7A0000CC3A2000C8C
S2140057E0C3B7000007BD0010AFE000000FBD0010FB
S2140057F0D7B700006498001877180018040F003018
S214005800930F0007040F0039A30F000564980018D3
S214005810771800180F180030D4D80000A800001A17
S2140058206498001877180018040F0041930F0008BA
S214005830040F005AA30F0006649800187718001883
S2140058400F1800410718000AD4D80000A800000E60
S2140058506498001877180018040F0061930F00086A
S214005860040F007AA30F0006649800187718001833
S2140058700F1800610718000AD4D80000A80000021C
S21400588000001000A8000006C0D800009B0500021B
S21400589004170001A80000010000B800001710005F
S2140058A0C3B7000007BD0010AFE000000FBD00301A
S2140058B0D7B50010D7B60014D7B70018D7BF001C4E
S2140058C00004B800D7A500340006B0000000A80009
S2140058D0A800000106F70001CEE40000B3FFFFAA0F
S2140058E08440FFFCCEF80000040F002B870F000456
S2140058F004180001D7B8002806F70001A800000920
S214005900CEF80000040F002D870F00040418FFFFD8
S214005910D7B8002806F70001A80000020418000106
S214005920D7B8002882C000020418001086D80019D4
S214005930CEF80000040F0030870F0008CEF80001F4
S214005940040F0078830F0002040F0058870F00032F
S21400595006F7000204160010A800000E86C0000D10
S214005960CEF80000040F0030870F000306F7000192
S21400597004160008A80000070416000AA800000580
S2140059800016C0001AB8A800C3B8002C02B8A800B9
S21400599006F70001CEE400000016280007A6002C3B
S2140059A0B3FFFF928440FFF6C3B8003483000002C2
S2140059B0C3B80034D7170000C3B800281B15100062
S2140059C0C3B50010C3B60014C3B70018C3BF001C8D
S2140059D007BD0030AFE000000FBD0010D7B70000D5
S2140059E0A80000080004C000CF170000070400014C
S2140059F0CCAF0000DF0F00000005C0000705000167
S214005A00DF1700000006C0000F0600018700FFF544
S214005A10C3B7000007BD0010AFE000000FBD0030A8
S214005A20D7B10010D7B20014D7B30018D7B4001CF3
S214005A30D7B50020D7B60024D7B70028D7BF002C8C
S214005A400004B8000005B0000006A8000007A0008B
S214005A5000179800001690000016C0000017780087
S214005A600B0FC0002315C000271800021315C00036
S214005A7003178800A800000102B398000013200056
S214005A80001128000014C800B72000009040FFFA5C
S214005A90A80000010A5590000011200000122800FE
S214005AA00014C800B72000009040FFFA0013C000A2
S214005AB000127800A70F000F0011C0000013780036
S214005AC0870F000200128800A80000040011C00022
S214005AD000127800870F00010013880000132000D2
S214005AE00012280000153000B3FFFFBB02B3980079
S214005AF00A5590000013C000001278008F0FFFDFD9
S214005B000017C000001278009F0F00050017200045
S214005B10001228000015300000143800B3FFFFBF45
S214005B200013C000001678009F0F00050013200029
S214005B30001628000015300000143800B3FFFFB729
S214005B40C3B10010C3B20014C3B30018C3B4001C22
S214005B50C3B50020C3B60024C3B70028C3BF002CBB
S214005B6007BD0030AFE000000FBD0020D7BF00101B
S214005B70D7A40020D7A50024D7A60028D7A7002C96
S214005B80C3B8002000182000C3AF0028C3AE00240E
S214005B900DCE000111CF700001D82800000F300094
S214005BA0C3A7002CB3FFFF9DC3BF001007BD002096
S214005BB0AFE000000FBD0020D7BF0010B3FFE91410
S214005BC00002C0006702001874420018C3BF00102D
S214005BD007BD0020AFE000000FBD0020D7BF0010BB
S214005BE0D7A40020C3B80020DFB80020CFB800201C
S214005BF0040F000A870F00020404000DB3FFE90635
S214005C00CFA40020B3FFE904C3BF001007BD0020E7
S214005C10AFE000000FBD0020D7B70010D7BF0014BC
S214005C200004B800A8000003CEE40000B3FFFFEABB
S214005C3006F70001CEF800008700FFFBC3B7001090
S214005C40C3BF001407BD0020AFE000000FBD00205A
S214005C50D7B60010D7B70014D7BF00180004B80096
S214005C600000B0009AE0000206D600010817B8004F
S214005C7026F8000AD7B8001CC3B8001C830000032F
S214005C80C3A4001CB3FFFFF102C2B00006C20001AD
S214005C90C3B60010C3B70014C3BF001807BD00206A
S214005CA0AFE000000FBD0020D7B60010D7B7001435
S214005CB0D7BF0018D7A400200005B800D7A6002834
S214005CC00007B0009AC0000A001720000405002D47
S214005CD0C3B90020B72000000002B800C3B80028EF
S214005CE0C30F000005EF0001D70F00000816B00034
S214005CF026D8000AD7B8001CC3B8001C83000006CC
S214005D00C3A4002000172800C3A60028C3A7001CB1
S214005D10B3FFFFE40002B8000017200036D8000AE0
S214005D20071800306705001874A50018C3B90020CE
S214005D30B72000000002B800C3B80028C30F000058
S214005D4005EF0001D70F000000171000C3B60010C3
S214005D50C3B70014C3BF001807BD0020AFE00000A3
S214005D600FBD0020D7BF0010D7A40020D7A5002461
S214005D70D7A00018C3B80020C3AF00242B0FC00064
S214005D80D7B8001CC3B8001C83000006C3A4001CC0
S214005D90C3A50024B3FFFFF2C3AF001801E2C000A2
S214005DA0D7B80018C3B8001807020001C3BF001018
S214005DB007BD0020AFE000000FBD0030D7B70018C9
S214005DC0D7BF001CD7A400300005B800D7A60038FF
S214005DD0D7A7003CC3B8003CC3AF00402B0FC000A1
S214005DE0D7B8002CC3B8002C8300000AC3A4003028
S214005DF000172800C3A60038C3A7002CC3B800406D
S214005E00D7B80010C3B80044D7B80014B3FFFFEAF1
S214005E100002B800C3B8004483000010001720003A
S214005E20C3B8003CC3AF00403B0FC0007C01C3FFBB
S214005E304C21D9F100380800CC250000C3B9003049
S214005E40B72000000002B800C3B80038C30F000037
S214005E5005EF0001D70F0000A800000F0017200074
S214005E60C3B8003CC3AF00403B0FC0007C01C3FF7B
S214005E704C21D9E000380800CC250000C3B900301A
S214005E80B72000000002B800C3B80038C30F0000F7
S214005E9005EF0001D70F000000171000C3B7001869
S214005EA0C3BF001C07BD0030AFE000000FBD0030D0
S214005EB0D7B30010D7B40014D7B50018D7B6001C57
S214005EC0D7B70020D7BF00240004B8000005B000F4
S214005ED00006A8000007A000C3B8004000189800FD
S214005EE0A8000009001620006665001874A50018B2
S214005EF00017C800B72000000002B000C2B80000BB
S214005F0007180001D6B800000014C0000F140001E6
S214005F10A300FFF400161000C3B30010C3B40014AF
S214005F20C3B50018C3B6001CC3B70020C3BF002407
S214005F3007BD0030AFE000000FBD0070D7B00018FE
S214005F40D7B1001CD7B20020D7B30024D7B400289E
S214005F50D7B5002CD7B60030D7B70034D7BF003837
S214005F600004B8000005B0000006A8000007A00066
S214005F70D7A0006CA80001C966780018771800182A
S214005F8087000002C3A2006CA80001C6001620000D
S214005F906665001874A500180017C800B720000032
S214005FA00002B000C3B8006C07180001D7B8006C38
S214005FB00015C00007150001CF1800000018980053
S214005FC06718001877180018040F0025870FFFEAD7
S214005FD00015C00007150001CF13000066780018F2
S214005FE077180018040F002D870F0006041800010C
S214005FF0001888000015C00007150001CF13000028
S214006000A8000001000088006678001877180018BD
S214006010040F0030870F0005041000300015C00084
S21400602007150001CF130000A8000001041000208F
S21400603000009000A80000090418000A131290003F
S21400604066780018771800180F180030025890006D
S2140060500015C00007150001CF1300006678001871
S21400606077180018040F0030930F0002040F003951
S2140060708B0FFFF16678001877180018040F00647D
S214006080870F0026069800040018A000C318FFFC1F
S214006090D7B80064C3A40064B3FFFEECD7A20068C0
S2140060A08A40000B8620000A0017200000162800F1
S2140060B007A6006CC3B800680A58380066180018AF
S2140060C077180018D7B80010B3FFFF780002B000AA
S2140060D0001720000016280007A6006CC3A700645F
S2140060E0B3FFFEF00002B0008A40016C8220016B14
S2140060F0001720000016280007A6006CC3B800682A
S2140061000A5838006618001877180018D7B8001014
S214006110B3FFFF660002B000A800016066780018B2
S21400612077180018040F0075830F0006040F006F21
S214006130830F0004040F0078830F0002040F00583A
S214006140870F005C069800040018A000C318FFFC28
S214006150D7B80060C3A400606678001877180018E7
S214006160040F006F870F000304180008D7B800500C
S214006170A800000D6678001877180018040F00783D
S214006180830F0002040F0058870F00030418001046
S214006190D7B8004CA80000020418000AD7B8004C74
S2140061A0C3B8004CD7B80050C3B800500018280039
S2140061B0B3FFFEEBD7A200688A40000B8620000AD9
S2140061C0001720000016280007A6006CC3B8006859
S2140061D00A5838006618001877180018D7B8001044
S2140061E0B3FFFF320002B0000017200000162800A0
S2140061F007A6006CC3A7006066780018771800181A
S214006200040F006F870F000304180008D7B8004873
S214006210A800000D6678001877180018040F00789C
S214006220830F0002040F0058870F000304180010A5
S214006230D7B80044A80000020418000AD7B80044E3
S214006240C3B80044D7B80048C3B80048D7B8001051
S2140062506678001877180018040F0058870F000398
S21400626004180001D7B80040A8000001D7A00040DD
S214006270C3B80040D7B80014B3FFFECF0002B0008A
S2140062808A4001068220010500172000001628001B
S21400629007A6006CC3B800680A58380066180018CD
S2140062A077180018D7B80010B3FFFF000002B00040
S2140062B0A80000FA6678001877180018040F006C1B
S2140062C0870F00A50015C00007150001CF130000BA
S2140062D06678001877180018040F0064870F0026E9
S2140062E0069800040018A000C318FFFCD7B8005892
S2140062F0C3A40058B3FFFE55D7A200688A40000B1F
S2140063008620000A001720000016280007A6006C4A
S214006310C3B800680A5838006618001877180018BE
S214006320D7B80010B3FFFEE10002B000001720004F
S2140063300016280007A6006CC3A70058B3FFFE5936
S2140063400002B0008A4000D5822000D4001720004A
S2140063500016280007A6006CC3B800680A58380064
S2140063606618001877180018D7B80010B3FFFECFCD
S2140063700002B000A80000C9667800187718001858
S214006380040F0075830F0006040F006F830F0004D0
S214006390040F0078830F0002040F0058870F005C7C
S2140063A0069800040018A000C318FFFCD7B80054D5
S2140063B0C3A400546678001877180018040F006FFE
S2140063C0870F000304180008D7B80050A800000D77
S2140063D06678001877180018040F0078830F0002FC
S2140063E0040F0058870F000304180010D7B8004C9D
S2140063F0A80000020418000AD7B8004CC3B8004C26
S214006400D7B80050C3B8005000182800B3FFFE5499
S214006410D7A200688A40000B8620000A00172000DA
S2140064200016280007A6006CC3B800680A58380093
S2140064306618001877180018D7B80010B3FFFE9B30
S2140064400002B000001720000016280007A6006C07
S214006450C3A700546678001877180018040F006F5A
S214006460870F000304180008D7B80048A800000DDE
S2140064706678001877180018040F0078830F00025B
S214006480040F0058870F000304180010D7B8004404
S214006490A80000020418000AD7B80044C3B8004495
S2140064A0D7B80048C3B80048D7B8001066780018B8
S2140064B077180018040F0058870F0003041800010F
S2140064C0D7B80040A8000001D7A00040C3B80040DD
S2140064D0D7B80014B3FFFE380002B0008A40006F41
S2140064E08220006E001720000016280007A6006C09
S2140064F0C3B800680A5838006618001877180018DD
S214006500D7B80010B3FFFE690002B000A800006311
S214006510001620000405006C0017C800B720000015
S2140065200002B000C3B8006C07180001D7B8006CB2
S214006530001620006665001874A500180017C8002D
S214006540B72000000002B000C3B8006C07180001B6
S214006550D7B8006CA80000516678001877180018A5
S214006560040F0073870F0032069800040018A0007E
S214006570C318FFFCD7B8005CC3A4005CB3FFFBCC19
S214006580D7A200688A400015862000140017200055
S2140065900016280007A6006CC3B800680A58380022
S2140065A06618001877180018D7B80010B3FFFE3F1B
S2140065B00002B000A800000900162000666500185A
S2140065C074A500180017C800B72000000002B0002D
S2140065D0C3B8006C07180001D7B8006CC3B8005CDD
S2140065E0070F0001D7AF005CCF1800000018980016
S2140065F067180018771800188700FFEF8A400027F2
S21400660082200026001720000016280007A6006C2F
S214006610C3B800680A5838006618001877180018BB
S214006620D7B80010B3FFFE210002B000A800001B80
S2140066306678001877180018040F0063870F000E9E
S214006640069800040018A000CF18FFFF0018980056
S214006650001620006665001874A500180017C8000C
S214006660B72000000002B000C3B8006C0718000195
S214006670D7B8006CA8000009001620006665001850
S21400668074A500180017C800B72000000002B0006C
S214006690C3B8006C07180001D7B8006CABFFFE4407
S2140066A000001000C3B00018C3B1001CC3B2002025
S2140066B0C3B30024C3B40028C3B5002CC3B600304F
S2140066C0C3B70034C3BF003807BD0070AFE000009A
S2140066D00FBD0020D7BF0010D7A40020D7A50024E8
S2140066E0C3B80024DFB80024CFA40024B3FFFD3ACB
S2140066F0C3A20020C3BF001007BD0020AFE000000B
S2140067000FBD0020D7BF0010D7A40020D7A50024B7
S2140067107C01E0004C2166D000012000000028002B
S214006720C3A60020C3A70024B3FFFE03D7A2001C05
S214006730C3A2001CC3BF001007BD0020AFE00000CE
S2140067400FBD0020D7BF0010D7A40020D7A5002477
S214006750D7A60028D7A7002C07B80024D7B800185B
S214006760C3A40020C3A50018B3FFFFE5D7A2001CF2
S214006770C3A2001CC3BF001007BD0020AFE000008E
S214006780DC85000004820001AFE000000FBD0020A1
S214006790D7B70010D7BF0014D7A40020D7A5002471
S2140067A0D7A600287C01E0004C216780000120006D
S2140067B0C3A50020C3A60024C3A70028B3FFFDDEA0
S2140067C00002B800C3B8002002F8C000DF000000D6
S2140067D000171000C3B70010C3BF001407BD002089
S2140067E0AFE000000FBD0020D7BF0010D7A40020E8
S2140067F0D7A50024D7A60028D7A7002C07B80028BE
S214006800D7B80018C3A40020C3A50024C3A6001848
S214006810B3FFFFDED7A2001CC3A2001CC3BF00103C
S21400682007BD0020AFE00000AFE000007C01F020D4
S21400683000014000C102000044420001AFE0000039
S2140068400FBD000CD7BF0008D7B00004D7B10000BA
S214006850B000004500408000040800F086080002F2
S214006860B0000041ABFFFFFAB000003F00408800D8
S2140068708230FFFD040800F082280001A80000080E
S214006880B00000398450FFF8020020007C01E000D0
S2140068904C2169C400012800B000003EA800002D6D
S2140068A0B0000031040800F08448FFFDB000002E60
S2140068B08050000280510007ABFFFFF9B000002AAD
S2140068C0040800F08448FFFDB00000278451FFFB59
S2140068D0A8000006B0000024040800F08448FFFD6D
S2140068E0B00000218450FFFBA8000000040800123E
S2140068F082080005040800598208000304080014F2
S2140069008208000DA8000006022020007C01E0009E
S2140069104C216AC400012800B000001EA800000D2B
S214006920020020007C01E0004C2169C40001280020
S214006930B0000018A8000007022020007C01E0003C
S2140069404C2169C400012800B00000124442009F98
S214006950A8000000C3B10000C3B00004C3BF000815
S21400696007BD000CAFE000007C01F02000014000F5
S214006970C1090000452900018120FFFDC102000475
S214006980040900E08049FFFA040900E18049FFF8A5
S214006990AFE000000FBD0008D7BF0004D7B000006E
S2140069A0449000FF02054000D10200008440000130
S2140069B002001000C3B00000C3BF000407BD0008FB
S2140069C0AFE0000000000000000000000000000033
S2140069D000095E00000000000071310000007973BD
S2140069E06177320000637864653433000020766691
S2140069F074723500006E6268677A360000006D6A51
S214006A0075373800002C6B696F303900002E2D6CFE
S214006A1000700000000000000000000000000D2BC9
S214006A2000230000003C00000000080000000000FA
S214006A30000000000000000000001B000000000036
S214006A400000000000000000000000000000000041
S214006A500000000000000000000000000000000031
S214006A600000000000000000000000000000000021
S214006A700000000000000000000000000000000011
S214006A800000000000000000000000000000000001
S214006A9000000000000000000000000000000000F1
S214006AA000000000000000000000000000000000E1
S214006AB000000000000000000000000000000000D1
S214006AC000000000000000000000000000000000C1
S214006AD000095E000000000000512100000059532C
S214006AE041572200004358444524330000205646B0
S214006AF054522500004E4248475A260000004D4A90
S214006B00552F2800003B4B494F3D2900003A5F4C6B
S214006B1000500000000000000000000000000D2AE9
S214006B2000270000003E00000000080000000000F3
S214006B30000000000000000000001B000000000035
S214006B400000000000000000000000000000000040
S214006B500000000000000000000000000000000030
S214006B600000000000000000000000000000000020
S214006B700000000000000000000000000000000010
S214006B800000000000000000000000000000000000
S214006B9000000000000000000000000000000000F0
S214006BA000000000000000000000000000000000E0
S214006BB000000000000000000000000000000000D0
S214006BC0000000000FBD0004D7BF0000B000008C1E
S214006BD07C01C3FF4C21E5D400014000D500000035
S214006BE07C01C3FF4C21E5D800014000D500000021
S214006BF0B0000070B0000061C3BF000007BD000415
S214006C00AFE0000004020001AFE000000FBD000886
S214006C10D7BF0004D7B00000449000FFB000004D7E
S214006C2004080020960800177C01C3FF4C21E5D01D
S214006C3000014000C10900004E100700D5300000DA
S214006C4005290004D50900007C01C3FF4C21E5D8C6
S214006C5000014000C109000005290001D509000017
S214006C60040A0050852A0002B0000013B000001C81
S214006C70B0000042C3B00000C3BF000407BD000858
S214006C80AFE000000408000D86080002B000000A0D
S214006C90ABFFFFF70408000A86080002B0000010E9
S214006CA0ABFFFFF30408000886080002B000001CD3
S214006CB0ABFFFFEFABFFFFEE0FBD0004D7BF00003A
S214006CC07C01C3FF4C21E5D800014000D500000040
S214006CD0B0000038C3BF000007BD0004AFE00000EE
S214006CE00FBD0004D7BF00007C01C3FF4C21E5D4D4
S214006CF000014000C1090000040A001D812A0004AA
S214006D0005290001D5090000B000002AA8000001EE
S214006D10B0000048C3BF000007BD0004AFE000009D
S214006D200FBD0004D7BF00007C01C3FF4C21E5D88F
S214006D3000014000C1090000812000030D29000168
S214006D40D5090000B000001BC3BF000007BD00044B
S214006D50AFE000007C01C3FF4C21E5D000014000FD
S214006D60C10800007C01C3FF4C21E5DC000148009F
S214006D70C12A0000D50A0000AFE000007C01C3FF76
S214006D804C21E5D000014000C10800007C01C3FF93
S214006D904C21E5DC00014800C10A0000D52A0000AD
S214006DA07C0100004C21875F00015000D50A0000DE
S214006DB0AFE000007C01F010000148007C01C3FF3A
S214006DC04C21E5D400014000C10A0000654A0009D4
S214006DD0012A48007C01C3FF4C21E5D80001400091
S214006DE0C10A0000654A0002012A48007C01C3FF70
S214006DF04C21E5D000014000D5090000AFE00000BE
S214006E00040B07207C01F010000140000409001E5E
S214006E10040A0050D50B0000050800040D4A0001C6
S214006E208540FFFC050800C00D2900018520FFF8FD
S214006E30AFE000007C01F010000140000409001DD6
S214006E40040A0050C10B0200D50B00000508000420
S214006E500D4A00018540FFFB050800C00D29000112
S214006E608520FFF7040B0720040A0050D50B00000E
S214006E70050800040D4A00018540FFFCAFE0000055
S214006E80AFE000007C01F03000014000C1020000CD
S214006E9044420001AFE000007C01F03000014000F9
S214006EA0C1090000452900018120FFFDC102000440
S214006EB0AFE000007C01F03000014000C102000895
S214006EC044420001AFE000007C01F03000014000C9
S214006ED0C1090008452900018120FFFDD504000CEA
S214006EE0AFE000007C01F0304C21100000014000B3
S214006EF0C102000044420001AFE000007C01F03017
S214006F004C21100000014000C10900004529000185
S214006F108120FFFDC1020004AFE000007C01F030DC
S214006F204C21100000014000C1020008444200014C
S214006F30AFE000007C01F0304C2110000001400062
S214006F40C1090008452900018120FFFDD504000C79
S214006F50AFE000007C01000F4C21424000014000E1
S214006F607C01F04000014800C12A0000454A00208C
S214006F70854000040D0800018500FFFB04020000A8
S214006F80A8000001C122000CAFE000000FBD0018F1
S214006F90D7BF0014D7B00010D7B1000CD7B2000886
S214006FA0D7B30004D7B400000080800000A088009B
S214006FB07C01C00000C1900000E098000408007248
S214006FC082080004040800778208001C040200FF00
S214006FD0A800003400001000826000327C01F040FF
S214006FE00001400004090001D5090004D51100087D
S214006FF004090001D5090000C10200004449001040
S2140070008120FFFD44490008852000267C01F048C9
S2140070100001400004090200C10A0000D64A000030
S21400702005080004065200040D2900048520FFFA16
S214007030063100010E730001ABFFFFE600001000F2
S214007040826000187C01F04800014000040902003C
S214007050C24A0000D50A00000652000405080004D3
S2140070600D2900048520FFFA7C01F0400001400055
S21400707004090001D5090004D5110008040900051B
S214007080D5090000C1020000444900108120FFFD20
S2140070904449000885200003063100010E730001F4
S2140070A0ABFFFFE6C3B40000C3B30004C3B20008DE
S2140070B0C3B1000CC3B00010C3BF001407BD001856
S2140070C0AFE000000FBD0010D7B00000D7B100043D
S2140070D0D7B20008D7BF000C7C01C3FF4C21DA04EE
S2140070E000012000B3FFFACB000090000410000A55
S2140070F00E10000104040016B3FFFF8E7C01000C86
S2140071004C213500000188000E310001B3FFFF75E9
S2140071108440000B8620FFFC7C01C3FF4C21DA294B
S21400712000012000B3FFFABB8600FFF17C01C3FF1D
S2140071304C21DA3F00012000B3FFFAB6A800000F8A
S214007140B3FFFF6E040800068448000C0404000623
S214007150B3FFFF7804040063B3FFFF76B3FFFF6757
S214007160844000060410000466520008B3FFFF6364
S2140071704A4290000E1000018600FFFB001210002D
S214007180C3B00000C3B10004C3B20008C3BF000C04
S21400719007BD0010AFE000000FBD0018D7B000001C
S2140071A0D7B10004D7B20008D7B3000CD7B400108C
S2140071B0D7BF001400048000000588007C01C000D2
S2140071C0000140004906900000079800040800727D
S2140071D081100004040800778110001804020001E2
S2140071E0A800002B826000130E73000104040072D6
S2140071F0B3FFFF50041400200E9400086A342000E9
S214007200448400FFB3FFFF4B8680FFFB063100017E
S214007210B3FFFF3A8440001E041402000E940001DF
S214007220B3FFFF36DE420000065200018680FFFBF9
S214007230ABFFFFEC00001000A800001582600013F2
S2140072400E73000104040077B3FFFF3A0414002015
S2140072500E9400086A342000448400FFB3FFFF3514
S2140072608680FFFB06310001041402000E94000124
S214007270D2440000B3FFFF2F065200018680FFFBBA
S214007280B3FFFF1E84400002ABFFFFEC00001000BF
S214007290C3B00000C3B10004C3B20008C3B3000CFF
S2140072A0C3B40010C3BF001407BD0018AFE0000051
S2140072B045434F3332203E20000A0A45434F3332BF
S2140072C0204D616368696E65204D6F6E69746F72DC
S2140072D020312E310A0A0000C3FFC1ABE00004D003
S2140072E0E0000AF8C3FFC1A9E0000504E0000BC4F3
S2140072F0C3FFC1A7E0000528E0000C74C3FFC1A5CA
S214007300E000055CE0000DA4C3FFC1A3E00005A0FB
S214007310E0000F28C3FFC1A1E00005D4E0000FB8CD
S214007320C3FFC19FE0000608E0001070C3FFC19DC8
S214007330E000063CE000110CC3FFC20AE000067045
S214007340E00015D8C3FFC19BE00006A4E000167C51
S214007350C3FFC199E00006E8E0001810C3FFC1961D
S214007360E000072CE0001AB4C3FFC193E0000770EA
S214007370E0001BE8C3FFC190E00007B4E0001D2456
S214007380C3FFC18EE00007F8E0001E60C3FFC1899E
S214007390E000084CE00021D0C3FFC184E000087084
S2140073A0E000224000000011202020202020546809
S2140073B06973206576656E742077696C6C206E6FD5
S2140073C07420616C746572207468652073746174CF
S2140073D065206F6620746865204350552E0A004E5F
S2140073E04F54453A202573202573206F63637572CA
S2140073F0726564207768696C652065786563757466
S214007400696E672074686520636F6D6D616E642EAB
S2140074100A004100416E00746F6F206D616E792026
S214007420746F6B656E73206F6E206C696E650A00F4
S21400743020090A00626F6F74006C6F61640074004C
S2140074406D62006D68006D77006400720023007343
S2140074500063006200750061002B0068656C7000B8
S214007460696C6C6567616C206469736B206E756D02
S2140074706265720A00696C6C6567616C2073657280
S21400748069616C206C696E65206E756D6265720A46
S21400749000544C422073656C6563746F7220697388
S2140074A0206E6F74206F6E65206F66202770272011
S2140074B06F72202766270A0066007000696C6C658C
S2140074C067616C20544C4220696E6465780A0045FA
S2140074D06E7472794C6F28332920253038580A008C
S2140074E0456E747279486928322920253038580A42
S2140074F000496E64657828312920202025303858C8
S2140075000A00544C425B253032645D2020202070F7
S214007510616765202025303858202020206672615B
S2140075206D652020253038582020256320202563CF
S2140075300A00253038583A2020253032580A0025CF
S2140075403038583A2020253034580A00253038582C
S2140075503A2020253038580A002E002000253032E8
S2140075605800253038583A20200024252D32642033
S21400757020253038580A00696C6C6567616C20728B
S21400758065676973746572206E756D6265720A0050
S21400759024252D3264202025303858202020202015
S2140075A000696C6C6567616C20646174610A002513
S2140075B02D3335733A20257320282573290A006C4D
S2140075C061737420696E746572727570742061637D
S2140075D06B6E6F776C6564676564202020202020C2
S2140075E020203A20253032582020282573290A00EA
S2140075F06F6C6420696E7465727275707420656E47
S21400760061626C6520202020202020202020202061
S2140076102020203A20257320282573290A0070721E
S2140076206576696F757320696E74657272757074AD
S21400763020656E61626C652020202020202020209E
S214007640203A20257320282573290A00646973616F
S214007650626C656400656E61626C65640063757279
S21400766072656E7420696E746572727570742065CA
S2140076706E61626C652020202020202020202020A3
S2140076803A20257320282573290A006F6C6420751C
S214007690736572206D6F64652020202020202020D6
S2140076A020202020202020202020202020203A20BB
S2140076B0257320282573290A0070726576696F7510
S2140076C0732075736572206D6F64652020202020FE
S2140076D02020202020202020202020203A20257333
S2140076E020282573290A006B65726E656C00757319
S2140076F065720063757272656E74207573657220AC
S2140077006D6F64652020202020202020202020204F
S2140077102020202020203A20257320282573290A9F
S21400772000524F4D0052414D006F6666006F6E204E
S21400773000696E7465727275707420766563746F16
S21400774072202020202020202020202020202020E2
S214007750202020203A20257320282573290A00425D
S2140077607265616B20617420253038580A00253018
S21400777038583A2020253038582020202025730AF3
S21400778000696C6C6567616C20636F756E740A00C7
S21400779025730A0041534D202320253038583A20BF
S2140077A000696C6C6567616C2061646472657373F4
S2140077B00A00616464203D20253038582C207375FB
S2140077C062203D20253038580A00696C6C65676178
S2140077D06C207365636F6E64206E756D6265720AE9
S2140077E000696C6C6567616C206669727374206EE4
S2140077F0756D6265720A006E6F2068656C70206138
S2140078007661696C61626C6520666F7220272573ED
S214007810272C20736F7272790A00256300202000DF
S2140078205053572020002020202020787878782079
S2140078302056202055504F202049504F20204941A7
S214007840434B2020204D41534B0A000A002D2D2D7E
S2140078502D2D2D2D2D00253038580042726B2020FE
S2140078600050432020202530385820202020205B40
S21400787050435D2020202530385820202025730ACC
S214007880002020626F6F74203C6E3E202020202057
S21400789020202020206C6F616420616E6420657853
S2140078A065637574652066697273742073656374A6
S2140078B06F72206F66206469736B203C6E3E0A0010
S2140078C020206C6F6164203C6E3E2020202020200B
S2140078D0202020206C6F616420616E20532D72651D
S2140078E0636F72642066696C652066726F6D2073C4
S2140078F0657269616C206C696E65203C6E3E0A009C
S21400790020207420203C693E2066203C646174611F
S2140079103E20202073657420544C4220636F6E74A2
S214007920656E7473206174203C693E20746F206617
S21400793072616D65203C646174613E0A00202074AB
S21400794020203C693E2070203C646174613E20200B
S2140079502073657420544C4220636F6E74656E7499
S21400796073206174203C693E20746F2070616765E7
S214007970203C646174613E0A0020207420203C692B
S2140079803E20202020202020202020202073686FEA
S2140079907720544C4220636F6E74656E747320615A
S2140079A074203C693E0A00202074202020202020DD
S2140079B0202020202020202020202073686F772081
S2140079C0544C4220636F6E74656E74730A002020F8
S2140079D06D62203C616464723E203C646174613E6A
S2140079E02020736574206D656D6F727920627974DE
S2140079F065206174203C616464723E20746F203C94
S214007A00646174613E0A0020206D62203C616464FB
S214007A10723E20202020202020202073686F7720B0
S214007A206D656D6F72792062797465206174203C93
S214007A30616464723E0A0020206D622020202020AF
S214007A40202020202020202020202073686F7720F0
S214007A506D656D6F7279206279746520617420504F
S214007A60430A0020206D68203C616464723E203C1E
S214007A70646174613E2020736574206D656D6F725D
S214007A80792068616C66776F7264206174203C614F
S214007A906464723E20746F203C646174613E0A0028
S214007AA020206D68203C616464723E2020202020E7
S214007AB02020202073686F77206D656D6F727920A7
S214007AC068616C66776F7264206174203C616464E0
S214007AD0723E0A0020206D682020202020202020D2
S214007AE0202020202020202073686F77206D656D71
S214007AF06F72792068616C66776F7264206174209B
S214007B0050430A0020206D77203C616464723E205A
S214007B103C646174613E2020736574206D656D6FF2
S214007B20727920776F7264206174203C616464729D
S214007B303E20746F203C646174613E0A0020206D14
S214007B4077203C616464723E202020202020202084
S214007B502073686F77206D656D6F727920776F720E
S214007B6064206174203C616464723E0A0020206DCB
S214007B7077202020202020202020202020202020A9
S214007B802073686F77206D656D6F727920776F72DE
S214007B90642061742050430A0020206420203C6149
S214007BA06464723E203C636E743E20202064756DD3
S214007BB070203C636E743E20627974657320737423
S214007BC0617274696E67206174203C616464723E01
S214007BD00A0020206420203C616464723E2020203D
S214007BE020202020202064756D70203235362062DB
S214007BF079746573207374617274696E672061743A
S214007C00203C616464723E0A00202064202020200C
S214007C102020202020202020202020202064756D79
S214007C207020323536206279746573207374617201
S214007C3074696E672061742050430A002020722009
S214007C40203C7265673E203C646174613E202020C3
S214007C50736574207265676973746572203C72651B
S214007C60673E20746F203C646174613E0A002020E9
S214007C707220203C7265673E202020202020202095
S214007C80202073686F772072656769737465722049
S214007C903C7265673E0A00202072202020202020AB
S214007CA0202020202020202020202073686F77208E
S214007CB0616C6C207265676973746572730A002064
S214007CC0207020203C646174613E2020202020200B
S214007CD02020207365742050535720746F203C6416
S214007CE06174613E0A002020702020202020202081
S214007CF02020202020202020202073686F7720500E
S214007D0053570A0020202320203C616464723E20E2
S214007D1020202020202020207365742050432074CB
S214007D206F203C616464723E0A00202023202020DD
S214007D3020202020202020202020202020207368A3
S214007D406F772050430A0020207320203C636E7417
S214007D503E2020202020202020202073696E676C83
S214007D60652D73746570203C636E743E20696E7377
S214007D707472756374696F6E730A00202073202016
S214007D80202020202020202020202020202020739B
S214007D90696E676C652D73746570206F6E652069FB
S214007DA06E737472756374696F6E0A0020206320A8
S214007DB0203C636E743E202020202020202020209F
S214007DC0636F6E74696E7565206578656375746932
S214007DD06F6E203C636E743E2074696D65730A0096
S214007DE0202063202020202020202020202020204B
S214007DF020202020636F6E74696E75652065786537
S214007E00637574696F6E0A0020206220203C6164EE
S214007E1064723E20202020202020202073657420BD
S214007E20627265616B206174203C616464723E0A14
S214007E30002020622020202020202020202020201B
S214007E402020202020726573657420627265616B45
S214007E500A0020207520203C616464723E203C634A
S214007E606E743E202020756E617373656D626C655E
S214007E70203C636E743E20696E7374727320737454
S214007E80617274696E67206174203C616464723E3E
S214007E900A0020207520203C616464723E20202069
S214007EA0202020202020756E617373656D626C65DE
S214007EB020313620696E7374727320737461727425
S214007EC0696E67206174203C616464723E0A00201B
S214007ED02075202020202020202020202020202048
S214007EE0202020756E617373656D626C6520313677
S214007EF020696E73747273207374617274696E672E
S214007F002061742050430A0020206120203C6164D8
S214007F1064723E202020202020202020617373657C
S214007F206D626C65207374617274696E672061742B
S214007F30203C616464723E0A0020206120202020DC
S214007F402020202020202020202020202061737345
S214007F50656D626C65207374617274696E6720610A
S214007F60742050430A0020202B20203C6E756D3173
S214007F703E203C6E756D323E202061646420616E4A
S214007F8064207375627472616374203C6E756D3123
S214007F903E20616E64203C6E756D323E0A002020E5
S214007FA068656C70203C636D643E20202020202095
S214007FB0202073686F772068656C7020666F72206B
S214007FC03C636D643E0A00202068656C70202020AB
S214007FD0202020202020202020202073686F77205B
S214007FE061206C697374206F6620636F6D6D616EBF
S214007FF064730A0074797065202768656C70203C8D
S214008000636D643E2720746F206765742068656C16
S2140080107020666F72203C636D643E0A002020620A
S2140080206F6F7420202020626F6F7473747261709B
S2140080302066726F6D206469736B0A0020206C6F77
S2140080406164202020206C6F61642066726F6D2052
S21400805073657269616C206C696E650A0020207415
S2140080602020202020202073686F772F73657420CF
S214008070544C4220636F6E74656E74730A00202041
S2140080806D6220202020202073686F772F73657420
S214008090206D656D6F727920627974650A00202004
S2140080A06D6820202020202073686F772F736574FA
S2140080B0206D656D6F72792068616C66776F72648B
S2140080C00A0020206D7720202020202073686F77FC
S2140080D02F736574206D656D6F727920776F72648B
S2140080E00A002020642020202020202064756D7047
S2140080F0206D656D6F72790A002020722020202086
S21400810020202073686F772F736574207265676907
S214008110737465720A002020702020202020202002
S21400812073686F772F736574205053570A002020AA
S214008130232020202020202073686F772F736574FB
S2140081402050430A00202073202020202020207367
S214008150696E676C652D737465700A002020632055
S214008160202020202020636F6E74696E756520665F
S214008170726F6D20627265616B706F696E740A0053
S214008180202062202020202020207365742F726516
S21400819073657420627265616B706F696E740A0035
S2140081A020207520202020202020756E61737365A6
S2140081B06D626C650A00202061202020202020208F
S2140081C0617373656D626C650A0020202B20202089
S2140081D02020202061646420616E642073756274C0
S2140081E0726163740A00202068656C70202020206D
S2140081F06765742068656C700A0076616C69642037
S214008200636F6D6D616E6473206172653A0A00007B
S214008210C3FFD24A0000000700000000C3FFD2469A
S2140082200000000702000000C3FFD2420000000763
S21400823004000000C3FFD23D000000060600000058
S214008240C3FFD2390000000708000000C3FFD23485
S214008250000000060A000000C3FFD230000000073E
S2140082600C000000C3FFD22B000000060E0000002A
S214008270C3FFD2270000000610000000C3FFD22470
S2140082800000000612000000C3FFD2200000000617
S21400829014000000C3FFD21B0000000616000000FA
S2140082A0C3FFD2170000000618000000C3FFD21359
S2140082B0000000061A000000C3FFD20F00000006F0
S2140082C01C000000C3FFD20A000000021F000000CE
S2140082D0C3FFD2060000000820000000C3FFD20241
S2140082E00000000821000000C3FFD1FE00000008C7
S2140082F022000000C3FFD1F90000000823000000A0
S214008300C3FFD1F50000000824000000C3FFD1F031
S2140083100000000825000000C3FFD1EC00000008A4
S21400832026000000C3FFD1E7000000082700000079
S214008330C3FFD1E30000000828000000C3FFD1DE21
S2140083400000000829000000C3FFD1DC000000097F
S2140083502A000000C3FFD1D90000000A2B0000004D
S214008360C3FFD1D5000000092C000000C3FFD1D008
S2140083700000000A2D000000C3FFD1CB0000000063
S2140083802E000000C3FFD1C7000000002F00000031
S214008390C3FFD1C30000000430000000C3FFD1BFFC
S2140083A00000000431000000C3FFD1BA0000000442
S2140083B032000000C3FFD1B6000000043300000006
S2140083C0C3FFD1B10000000434000000C3FFD1ADEC
S2140083D00000000435000000C3FFD1A9000000041F
S2140083E036000000C3FFD1A50000000437000000DF
S2140083F0C3FFD1A00000000138000000C3FFD19BDE
S2140084000000000139000000C3FFD1970000000003
S2140084103A000000C3FFD192000000003B000000BD
S214008420C3FFD18D000000003C000000C3FFD188D0
S214008430000000003D0000007462776900746272FC
S21400844069007462777200746273006D76747300EC
S2140084506D76667300737462007374680073747765
S214008460006C646275006C6462006C646875006C15
S2140084706468006C647700726678007472617000DD
S2140084806A616C72006A616C006A72006A006267F8
S21400849074750062677400626765750062676500E0
S2140084A0626C747500626C7400626C657500626C58
S2140084B06500626E6500626571006C6468690073D1
S2140084C0617200736C7200736C6C00786E6F720071
S2140084D0786F72006F7200616E640072656D750071
S2140084E072656D006469767500646976006D756CFA
S2140084F075006D756C007375620061646400000041
S214008500C3FFD388C3FFD37DC3FFD364C3FFD34960
S214008510C3FFD333C3FFD322C3FFD311C3FFD2F9A4
S214008520C3FFD2DCC3FFD2C6C3FFD2ADE000290C26
S214008530E0002998E0002A64E0002B3CE0002C389C
S214008540E0002D40E0002E18E0002F80E00030F420
S214008550E000323CE000332C20090A2C00746172E3
S2140085606765742063616E6E6F7420626520726545
S214008570616368656400746172676574206973205E
S2140085806E6F7420616C69676E656400696D6D65F9
S21400859064696174652076616C7565206F757420FA
S2140085A06F662072616E676500696C6C6567616CEA
S2140085B020696D6D6564696174652076616C7565AA
S2140085C000696C6C6567616C2072656769737465B9
S2140085D07200746F6F20666577206F706572616ECB
S2140085E064730065786365737320746F6B656E7370
S2140085F0206F6E206C696E6500756E6B6E6F776EA1
S21400860020696E737472756374696F6E20666F721C
S2140086106D617400756E6B6E6F776E20696E737425
S21400862072756374696F6E206E616D6500656D703E
S2140086307479206C696E6500746F6F206D616E7959
S21400864020746F6B656E73206F6E206C696E6500AC
S214008650E00038A8E00038C4E00038E8E000390C54
S214008660E000393CE000396CE00039A0E0003A1048
S214008670E0003A80E0003AB8E0003AD8696C6C65F1
S21400868067616C20656E74727920696E20696E73FE
S2140086907472756374696F6E207461626C650A002B
S2140086A03F3F3F00252D37732024256400252D37B6
S2140086B073202425642C2425642C25303858002566
S2140086C02D3773202425642C2425642C242564004F
S2140086D02B002D00252D3773202425642C2425649B
S2140086E02C25732530345800252D37732024256417
S2140086F02C2425642C2530345800252D377320244F
S21400870025642C2530385800252D37732024256401
S2140087102C2530345800252D377320253038580046
S214008720252D377300000000E00041CCE0003F1C20
S214008730E0003F80E0004004E00041B8E00041CCAB
S214008740E00041B8E00040A0E0004118E0004178B9
S214008750436F6E6E656374696F6E20746F206C6F06
S21400876061642073657276657220636C6F736564EE
S2140087702E0A004572726F723A20756E6B6E6F77B6
S2140087806E2074797065206F6620532D7265636F56
S2140087907264210A004572726F723A2077726F6EA9
S2140087A06720636865636B73756D20696E20532D53
S2140087B07265636F7264210A004572726F723A20A6
S2140087C0696E636F6E73697374656E742062797414
S2140087D06520636F756E7420696E20532D72656315
S2140087E06F7264210A004572726F723A206D616C76
S2140087F0666F726D656420532D7265636F726421B7
S2140088000A0025730A004572726F723A20746F6F01
S214008810206D616E7920636861726163746572733E
S21400882020696E20532D7265636F7264210A0043BF
S2140088306F6E6E656374656420746F206C6F616420
S214008840207365727665722E0A00556E61626C65DD
S21400885020746F2065737461626C69736820636F3F
S2140088606E6E656374696F6E20746F206C6F6164E2
S214008870207365727665722E0A005265717565738F
S214008880742074696D6564206F75742E2E2E0A0030
S214008890547279696E6720746F20636F6E6E6563BD
S2140088A07420746F206C6F616420736572766572D5
S2140088B02E2E2E0A000000004D4252207369676E6D
S2140088C06174757265206D697373696E67210A003D
S2140088D04469736B206572726F72210A0044697373
S2140088E06B20776974682030782530385820736597
S2140088F063746F727320666F756E642C20626F6F80
S21400890074696E672E2E2E0A004469736B206E6F94
S2140089107420666F756E64210A000000C3FFD9A636
S214008920C3FFD988C3FFD967C3FFD949C3FFD93668
S214008930C3FFD924C3FFD924C3FFD924C3FFD91545
S214008940C3FFD924C3FFD924C3FFD924C3FFD92426
S214008950C3FFD924C3FFD905C3FFD924C3FFD8EF6B
S214008960C3FFD8D1C3FFD8B0C3FFD893C3FFD8780E
S214008970C3FFD865C3FFD851C3FFD83BC3FFD82178
S214008980C3FFD804C3FFD7F2C3FFD7F2C3FFD7F2A3
S214008990C3FFD7F2C3FFD7F2C3FFD7F2010101012D
S2140089A001010101010101010101010101010101B2
S2140089B0010101010101010101010101020202029E
S2140089C00202020202020304030401000101010183
S2140089D0010101010101010101010101E00044C0A2
S2140089E0E00044D4E00044E8E00044FCE000451029
S2140089F0E0004524E0004538E000454CE0004560D6
S214008A00E0004574E0004660E0004678E00046FC82
S214008A10E000474C756E6578706563746564202564
S214008A2073206F636375727265640A0063616E6EAD
S214008A306F742073696E676C652D7374657020693A
S214008A406E737472756374696F6E207769746820CC
S214008A506F70636F6465203078253032580A006383
S214008A60616E6E6F7420636F6D7075746520636FD2
S214008A706E646974696F6E20636F64652025640A8E
S214008A80003C657863657074696F6E206E756D6204
S214008A906572206F7574206F6620626F756E6473E2
S214008AA03E00756E6B6E6F776E20657863657074CA
S214008AB0696F6E0070726976696C656765642061BF
S214008AC064647265737320657863657074696F6E2D
S214008AD000696C6C6567616C2061646472657373B1
S214008AE020657863657074696F6E00544C42206927
S214008AF06E76616C696420657863657074696F6E04
S214008B0000544C42207772697465206578636570FE
S214008B1074696F6E00544C42206D697373206578DB
S214008B2063657074696F6E007472617020696E732D
S214008B307472756374696F6E2065786365707469A6
S214008B406F6E0064697669646520696E7374727509
S214008B506374696F6E20657863657074696F6E0004
S214008B6070726976696C6567656420696E73747285
S214008B70756374696F6E20657863657074696F6E6F
S214008B8000696C6C6567616C20696E7374727563DE
S214008B9074696F6E20657863657074696F6E0062C5
S214008BA075732074696D656F75742065786365707C
S214008BB074696F6E0074696D657220696E74657293
S214008BC072757074006469736B20696E7465727276
S214008BD075707400756E6B6E6F776E20696E746557
S214008BE07272757074006B6579626F617264206969
S214008BF06E74657272757074007465726D696E61FC
S214008C006C203120726563656976657220696E74C2
S214008C10657272757074007465726D696E616C2031
S214008C2031207472616E736D697474657220696E3A
S214008C3074657272757074007465726D696E616CBD
S214008C40203020726563656976657220696E74658A
S214008C507272757074007465726D696E616C203026
S214008C60207472616E736D697474657220696E74B7
S214008C70657272757074000020000D00E00057CC1D
S214008C80E00057CCE00057CCE00057CCE00057CCD3
S214008C90303132333435363738396162636465666D
S214008CA00030313233343536373839414243444563
S214008CB046000000547279696E6720746F20636FF7
S214008CC06E6E65637420746F206469736B207365C1
S214008CD0727665722E2E2E0A005265717565737453
S214008CE02074696D6564206F75742E2E2E0A0055EB
S214008CF06E61626C6520746F2065737461626C6966
S214008D00736820636F6E6E656374696F6E20746F30
S214008D10206469736B207365727665722E0A000094
S804000000FB
/monitor/monitor-digilent/boot.c
0,0 → 1,47
/*
* boot.c -- bootstrap from disk
*/
 
 
#include "common.h"
#include "stdarg.h"
#include "romlib.h"
#include "boot.h"
#include "cpu.h"
#include "mmu.h"
#include "start.h"
 
 
void boot(int dskno) {
Word capacity;
Byte sig1, sig2;
 
capacity = dskcap(dskno);
if (capacity == 0) {
printf("Disk not found!\n");
return;
}
printf("Disk with 0x%08X sectors found, booting...\n", capacity);
if (dskio(dskno, 'r', 0, PHYS_BOOT, 1) != 0) {
printf("Disk error!\n");
return;
}
sig1 = mmuReadByte(VIRT_BOOT + 512 - 2);
sig2 = mmuReadByte(VIRT_BOOT + 512 - 1);
if (sig1 != 0x55 || sig2 != 0xAA) {
printf("MBR signature missing!\n");
return;
}
/*
* Boot convention:
* $16 disk number of boot disk
* $17 start sector number of disk or partition to boot
* $18 total number of sectors of disk or partition to boot
*/
cpuSetReg(16, dskno);
cpuSetReg(17, 0);
cpuSetReg(18, capacity);
cpuSetReg(29, TOS_BOOT);
cpuSetPC(VIRT_BOOT);
cpuRun();
}
/monitor/monitor-digilent/boot.h
0,0 → 1,18
/*
* boot.h -- bootstrap from disk
*/
 
 
#ifndef _BOOT_H_
#define _BOOT_H_
 
 
#define PHYS_BOOT 0x00000000 /* where to load the bootstrap */
#define VIRT_BOOT 0xC0000000 /* where to start the bootstrap */
#define TOS_BOOT 0xC0001000 /* top of stack for bootstrap */
 
 
void boot(int dskno);
 
 
#endif /* _BOOT_H_ */
/monitor/monitor-digilent/monitor.bin Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
monitor/monitor-digilent/monitor.bin Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: monitor/monitor-digilent/command.c =================================================================== --- monitor/monitor-digilent/command.c (nonexistent) +++ monitor/monitor-digilent/command.c (revision 16) @@ -0,0 +1,887 @@ +/* + * command.c -- command interpreter + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "getline.h" +#include "command.h" +#include "asm.h" +#include "disasm.h" +#include "load.h" +#include "boot.h" +#include "cpu.h" +#include "mmu.h" +#include "start.h" + + +#define MAX_TOKENS 10 + + +typedef struct { + char *name; + void (*hlpProc)(void); + void (*cmdProc)(char *tokens[], int n); +} Command; + +extern Command commands[]; +extern int numCommands; + + +static void help(void) { + printf("valid commands are:\n"); + printf(" help get help\n"); + printf(" + add and subtract\n"); + printf(" a assemble\n"); + printf(" u unassemble\n"); + printf(" b set/reset breakpoint\n"); + printf(" c continue from breakpoint\n"); + printf(" s single-step\n"); + printf(" # show/set PC\n"); + printf(" p show/set PSW\n"); + printf(" r show/set register\n"); + printf(" d dump memory\n"); + printf(" mw show/set memory word\n"); + printf(" mh show/set memory halfword\n"); + printf(" mb show/set memory byte\n"); + printf(" t show/set TLB contents\n"); + printf(" load load from serial line\n"); + printf(" boot bootstrap from disk\n"); + printf("type 'help ' to get help for \n"); +} + + +static void help00(void) { + printf(" help show a list of commands\n"); + printf(" help show help for \n"); +} + + +static void help01(void) { + printf(" + add and subtract and \n"); +} + + +static void help02(void) { + printf(" a assemble starting at PC\n"); + printf(" a assemble starting at \n"); +} + + +static void help03(void) { + printf(" u unassemble 16 instrs starting at PC\n"); + printf(" u unassemble 16 instrs starting at \n"); + printf(" u unassemble instrs starting at \n"); +} + + +static void help04(void) { + printf(" b reset break\n"); + printf(" b set break at \n"); +} + + +static void help05(void) { + printf(" c continue execution\n"); + printf(" c continue execution times\n"); +} + + +static void help06(void) { + printf(" s single-step one instruction\n"); + printf(" s single-step instructions\n"); +} + + +static void help07(void) { + printf(" # show PC\n"); + printf(" # set PC to \n"); +} + + +static void help08(void) { + printf(" p show PSW\n"); + printf(" p set PSW to \n"); +} + + +static void help09(void) { + printf(" r show all registers\n"); + printf(" r show register \n"); + printf(" r set register to \n"); +} + + +static void help10(void) { + printf(" d dump 256 bytes starting at PC\n"); + printf(" d dump 256 bytes starting at \n"); + printf(" d dump bytes starting at \n"); +} + + +static void help11(void) { + printf(" mw show memory word at PC\n"); + printf(" mw show memory word at \n"); + printf(" mw set memory word at to \n"); +} + + +static void help12(void) { + printf(" mh show memory halfword at PC\n"); + printf(" mh show memory halfword at \n"); + printf(" mh set memory halfword at to \n"); +} + + +static void help13(void) { + printf(" mb show memory byte at PC\n"); + printf(" mb show memory byte at \n"); + printf(" mb set memory byte at to \n"); +} + + +static void help14(void) { + printf(" t show TLB contents\n"); + printf(" t show TLB contents at \n"); + printf(" t p set TLB contents at to page \n"); + printf(" t f set TLB contents at to frame \n"); +} + + +static void help15(void) { + printf(" load load an S-record file from serial line \n"); +} + + +static void help16(void) { + printf(" boot load and execute first sector of disk \n"); +} + + +static Bool getHexNumber(char *str, Word *valptr) { + char *end; + + *valptr = strtoul(str, &end, 16); + return *end == '\0'; +} + + +static Bool getDecNumber(char *str, int *valptr) { + char *end; + + *valptr = strtoul(str, &end, 10); + return *end == '\0'; +} + + +static void showPC(void) { + Word pc, psw; + Word instr; + + pc = cpuGetPC(); + psw = cpuGetPSW(); + instr = mmuReadWord(pc); + printf("PC %08X [PC] %08X %s\n", + pc, instr, disasm(instr, pc)); +} + + +static void showBreak(void) { + Word brk; + + brk = cpuGetBreak(); + printf("Brk "); + if (cpuTestBreak()) { + printf("%08X", brk); + } else { + printf("--------"); + } + printf("\n"); +} + + +static void showPSW(void) { + Word psw; + int i; + + psw = cpuGetPSW(); + printf(" xxxx V UPO IPO IACK MASK\n"); + printf("PSW "); + for (i = 31; i >= 0; i--) { + if (i == 27 || i == 26 || i == 23 || i == 20 || i == 15) { + printf(" "); + } + printf("%c", psw & (1 << i) ? '1' : '0'); + } + printf("\n"); +} + + +static void doHelp(char *tokens[], int n) { + int i; + + if (n == 1) { + help(); + } else if (n == 2) { + for (i = 0; i < numCommands; i++) { + if (strcmp(commands[i].name, tokens[1]) == 0) { + (*commands[i].hlpProc)(); + return; + } + } + printf("no help available for '%s', sorry\n", tokens[1]); + } else { + help00(); + } +} + + +static void doArith(char *tokens[], int n) { + Word num1, num2, num3, num4; + + if (n == 3) { + if (!getHexNumber(tokens[1], &num1)) { + printf("illegal first number\n"); + return; + } + if (!getHexNumber(tokens[2], &num2)) { + printf("illegal second number\n"); + return; + } + num3 = num1 + num2; + num4 = num1 - num2; + printf("add = %08X, sub = %08X\n", num3, num4); + } else { + help01(); + } +} + + +static void doAssemble(char *tokens[], int n) { + Word addr; + Word psw; + char prompt[30]; + char *line; + char *msg; + Word instr; + + if (n == 1) { + addr = cpuGetPC(); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + } else { + help02(); + return; + } + addr &= ~0x00000003; + psw = cpuGetPSW(); + while (1) { + sprintf(prompt, "ASM # %08X: ", addr); + line = getLine(prompt); + if (*line == '\0' || *line == '\n') { + break; + } + addHist(line); + msg = asmInstr(line, addr, &instr); + if (msg != NULL) { + printf("%s\n", msg); + } else { + mmuWriteWord(addr, instr); + addr += 4; + } + } +} + + +static void doUnassemble(char *tokens[], int n) { + Word addr, count; + Word psw; + int i; + Word instr; + + if (n == 1) { + addr = cpuGetPC(); + count = 16; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + count = 16; + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &count)) { + printf("illegal count\n"); + return; + } + if (count == 0) { + return; + } + } else { + help03(); + return; + } + addr &= ~0x00000003; + psw = cpuGetPSW(); + for (i = 0; i < count; i++) { + instr = mmuReadWord(addr); + printf("%08X: %08X %s\n", + addr, instr, disasm(instr, addr)); + if (addr + 4 < addr) { + /* wrap-around */ + break; + } + addr += 4; + } +} + + +static void doBreak(char *tokens[], int n) { + Word addr; + + if (n == 1) { + cpuResetBreak(); + showBreak(); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + addr &= ~0x00000003; + cpuSetBreak(addr); + showBreak(); + } else { + help04(); + } +} + + +static void doContinue(char *tokens[], int n) { + Word count, i; + Word addr; + + if (n == 1) { + count = 1; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &count) || count == 0) { + printf("illegal count\n"); + return; + } + } else { + help05(); + return; + } + for (i = 0; i < count; i++) { + cpuRun(); + } + addr = cpuGetPC(); + printf("Break at %08X\n", addr); + showPC(); +} + + +static void doStep(char *tokens[], int n) { + Word count, i; + + if (n == 1) { + count = 1; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &count) || count == 0) { + printf("illegal count\n"); + return; + } + } else { + help06(); + return; + } + for (i = 0; i < count; i++) { + cpuStep(); + } + showPC(); +} + + +static void doPC(char *tokens[], int n) { + Word addr; + + if (n == 1) { + showPC(); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + addr &= ~0x00000003; + cpuSetPC(addr); + showPC(); + } else { + help07(); + } +} + + +static void explainPSW(Word data) { + int i; + + printf("interrupt vector : %s (%s)\n", + data & PSW_V ? "on " : "off", + data & PSW_V ? "RAM" : "ROM"); + printf("current user mode : %s (%s)\n", + data & PSW_UM ? "on " : "off", + data & PSW_UM ? "user" : "kernel"); + printf("previous user mode : %s (%s)\n", + data & PSW_PUM ? "on " : "off", + data & PSW_PUM ? "user" : "kernel"); + printf("old user mode : %s (%s)\n", + data & PSW_OUM ? "on " : "off", + data & PSW_OUM ? "user" : "kernel"); + printf("current interrupt enable : %s (%s)\n", + data & PSW_IE ? "on " : "off", + data & PSW_IE ? "enabled" : "disabled"); + printf("previous interrupt enable : %s (%s)\n", + data & PSW_PIE ? "on " : "off", + data & PSW_PIE ? "enabled" : "disabled"); + printf("old interrupt enable : %s (%s)\n", + data & PSW_OIE ? "on " : "off", + data & PSW_OIE ? "enabled" : "disabled"); + printf("last interrupt acknowledged : %02X (%s)\n", + (data & PSW_PRIO_MASK) >> 16, + exceptionToString((data & PSW_PRIO_MASK) >> 16)); + for (i = 15; i >= 0; i--) { + printf("%-35s: %s (%s)\n", + exceptionToString(i), + data & (1 << i) ? "on " : "off", + data & (1 << i) ? "enabled" : "disabled"); + } +} + + +static void doPSW(char *tokens[], int n) { + Word data; + + if (n == 1) { + data = cpuGetPSW(); + showPSW(); + explainPSW(data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &data)) { + printf("illegal data\n"); + return; + } + data &= 0x0FFFFFFF; + cpuSetPSW(data); + showPSW(); + explainPSW(data); + } else { + help08(); + } +} + + +static void doRegister(char *tokens[], int n) { + int i, j; + int reg; + Word data; + + if (n == 1) { + for (i = 0; i < 8; i++) { + for (j = 0; j < 4; j++) { + reg = 8 * j + i; + data = cpuGetReg(reg); + printf("$%-2d %08X ", reg, data); + } + printf("\n"); + } + showPSW(); + showBreak(); + showPC(); + } else if (n == 2) { + if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) { + printf("illegal register number\n"); + return; + } + data = cpuGetReg(reg); + printf("$%-2d %08X\n", reg, data); + } else if (n == 3) { + if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) { + printf("illegal register number\n"); + return; + } + if (!getHexNumber(tokens[2], &data)) { + printf("illegal data\n"); + return; + } + cpuSetReg(reg, data); + } else { + help09(); + } +} + + +static void doDump(char *tokens[], int n) { + Word addr, count; + Word psw; + Word lo, hi, curr; + int lines, i, j; + Word tmp; + Byte c; + + if (n == 1) { + addr = cpuGetPC(); + count = 16 * 16; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + count = 16 * 16; + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &count)) { + printf("illegal count\n"); + return; + } + if (count == 0) { + return; + } + } else { + help10(); + return; + } + psw = cpuGetPSW(); + lo = addr & ~0x0000000F; + hi = addr + count - 1; + if (hi < lo) { + /* wrap-around */ + hi = 0xFFFFFFFF; + } + lines = (hi - lo + 16) >> 4; + curr = lo; + for (i = 0; i < lines; i++) { + printf("%08X: ", curr); + for (j = 0; j < 16; j++) { + tmp = curr + j; + if (tmp < addr || tmp > hi) { + printf(" "); + } else { + c = mmuReadByte(tmp); + printf("%02X", c); + } + printf(" "); + } + printf(" "); + for (j = 0; j < 16; j++) { + tmp = curr + j; + if (tmp < addr || tmp > hi) { + printf(" "); + } else { + c = mmuReadByte(tmp); + if (c >= 32 && c <= 126) { + printf("%c", c); + } else { + printf("."); + } + } + } + printf("\n"); + curr += 16; + } +} + + +static void doMemoryWord(char *tokens[], int n) { + Word psw; + Word addr; + Word data; + Word tmpData; + + psw = cpuGetPSW(); + if (n == 1) { + addr = cpuGetPC(); + data = mmuReadWord(addr); + printf("%08X: %08X\n", addr, data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + data = mmuReadWord(addr); + printf("%08X: %08X\n", addr, data); + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &tmpData)) { + printf("illegal data\n"); + return; + } + data = tmpData; + mmuWriteWord(addr, data); + } else { + help11(); + } +} + + +static void doMemoryHalf(char *tokens[], int n) { + Word psw; + Word addr; + Half data; + Word tmpData; + + psw = cpuGetPSW(); + if (n == 1) { + addr = cpuGetPC(); + data = mmuReadHalf(addr); + printf("%08X: %04X\n", addr, data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + data = mmuReadHalf(addr); + printf("%08X: %04X\n", addr, data); + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &tmpData)) { + printf("illegal data\n"); + return; + } + data = (Half) tmpData; + mmuWriteHalf(addr, data); + } else { + help12(); + } +} + + +static void doMemoryByte(char *tokens[], int n) { + Word psw; + Word addr; + Byte data; + Word tmpData; + + psw = cpuGetPSW(); + if (n == 1) { + addr = cpuGetPC(); + data = mmuReadByte(addr); + printf("%08X: %02X\n", addr, data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + data = mmuReadByte(addr); + printf("%08X: %02X\n", addr, data); + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &tmpData)) { + printf("illegal data\n"); + return; + } + data = (Byte) tmpData; + mmuWriteByte(addr, data); + } else { + help13(); + } +} + + +static void doTLB(char *tokens[], int n) { + int index; + TLB_Entry tlbEntry; + Word data; + + if (n == 1) { + for (index = 0; index < TLB_SIZE; index++) { + tlbEntry = mmuGetTLB(index); + printf("TLB[%02d] page %08X frame %08X %c %c\n", + index, tlbEntry.page, tlbEntry.frame, + tlbEntry.write ? 'w' : '-', + tlbEntry.valid ? 'v' : '-'); + } + printf("Index(1) %08X\n", mmuGetIndex()); + printf("EntryHi(2) %08X\n", mmuGetEntryHi()); + printf("EntryLo(3) %08X\n", mmuGetEntryLo()); + } else if (n == 2) { + if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) { + printf("illegal TLB index\n"); + return; + } + tlbEntry = mmuGetTLB(index); + printf("TLB[%02d] page %08X frame %08X %c %c\n", + index, tlbEntry.page, tlbEntry.frame, + tlbEntry.write ? 'w' : '-', + tlbEntry.valid ? 'v' : '-'); + } else if (n == 3) { + help14(); + } else if (n == 4) { + if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) { + printf("illegal TLB index\n"); + return; + } + if (!getHexNumber(tokens[3], &data)) { + printf("illegal data\n"); + return; + } + tlbEntry = mmuGetTLB(index); + if (strcmp(tokens[2], "p") == 0) { + tlbEntry.page = data & PAGE_MASK; + } else + if (strcmp(tokens[2], "f") == 0) { + tlbEntry.frame = data & PAGE_MASK; + tlbEntry.write = data & TLB_WRITE ? true : false; + tlbEntry.valid = data & TLB_VALID ? true : false; + } else { + printf("TLB selector is not one of 'p' or 'f'\n"); + return; + } + mmuSetTLB(index, tlbEntry); + printf("TLB[%02d] page %08X frame %08X %c %c\n", + index, tlbEntry.page, tlbEntry.frame, + tlbEntry.write ? 'w' : '-', + tlbEntry.valid ? 'v' : '-'); + } else { + help14(); + } +} + + +static void doLoad(char *tokens[], int n) { + int serno; + + if (n == 2) { + if (!getDecNumber(tokens[1], &serno) || serno < 0 || serno > 1) { + printf("illegal serial line number\n"); + return; + } + load(serno); + } else { + help15(); + } +} + + +static void doBoot(char *tokens[], int n) { + int dskno; + + if (n == 2) { + if (!getDecNumber(tokens[1], &dskno) || dskno < 0 || dskno > 1) { + printf("illegal disk number\n"); + return; + } + boot(dskno); + } else { + help16(); + } +} + + +Command commands[] = { + { "help", help00, doHelp }, + { "+", help01, doArith }, + { "a", help02, doAssemble }, + { "u", help03, doUnassemble }, + { "b", help04, doBreak }, + { "c", help05, doContinue }, + { "s", help06, doStep }, + { "#", help07, doPC }, + { "p", help08, doPSW }, + { "r", help09, doRegister }, + { "d", help10, doDump }, + { "mw", help11, doMemoryWord }, + { "mh", help12, doMemoryHalf }, + { "mb", help13, doMemoryByte }, + { "t", help14, doTLB }, + { "load", help15, doLoad }, + { "boot", help16, doBoot }, +}; + +int numCommands = sizeof(commands) / sizeof(commands[0]); + + +static void doCommand(char *line) { + char *tokens[MAX_TOKENS]; + int n; + char *p; + int i; + + n = 0; + p = strtok(line, " \t\n"); + while (p != NULL) { + if (n == MAX_TOKENS) { + printf("too many tokens on line\n"); + return; + } + tokens[n++] = p; + p = strtok(NULL, " \t\n"); + } + if (n == 0) { + return; + } + for (i = 0; i < numCommands; i++) { + if (strcmp(commands[i].name, tokens[0]) == 0) { + (*commands[i].cmdProc)(tokens, n); + return; + } + } + help(); +} + + +static char *article(char firstLetterOfNoun) { + switch (firstLetterOfNoun) { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + return "An"; + default: + return "A"; + } +} + + +static void interactiveException(int exception) { + char *what; + + what = exceptionToString(exception); + printf("\n"); + printf("NOTE: %s %s occurred while executing the command.\n", + article(*what), what); + printf(" This event will not alter the state of the CPU.\n"); +} + + +void execCommand(char *line) { + MonitorState commandState; + + if (saveState(&commandState)) { + /* initialization */ + monitorReturn = &commandState; + doCommand(line); + } else { + /* an exception was thrown */ + interactiveException((userContext.psw & PSW_PRIO_MASK) >> 16); + } + monitorReturn = NULL; +} Index: monitor/monitor-digilent/asm.c =================================================================== --- monitor/monitor-digilent/asm.c (nonexistent) +++ monitor/monitor-digilent/asm.c (revision 16) @@ -0,0 +1,370 @@ +/* + * asm.c -- assembler + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "instr.h" +#include "asm.h" + + +#define MAX_TOKENS 10 + + +static char *msgs[] = { + /* 0 */ "too many tokens on line", + /* 1 */ "empty line", + /* 2 */ "unknown instruction name", + /* 3 */ "unknown instruction format", + /* 4 */ "excess tokens on line", + /* 5 */ "too few operands", + /* 6 */ "illegal register", + /* 7 */ "illegal immediate value", + /* 8 */ "immediate value out of range", + /* 9 */ "target is not aligned", + /* 10 */ "target cannot be reached" +}; + + +static Bool asmReg(char *token, int *reg) { + char *end; + + if (*token != '$') { + return false; + } + *reg = strtoul(token + 1, &end, 10); + if (*end != '\0') { + return false; + } + if (*reg < 0 || *reg >= 32) { + return false; + } + return true; +} + + +static Bool asmNum(char *token, unsigned int *val) { + char *end; + + *val = strtoul(token, &end, 16); + return *end == '\0'; +} + + +char *asmInstr(char *line, Word addr, Word *instrPtr) { + char *tokens[MAX_TOKENS]; + int n; + char *p; + Instr *instr; + Word result; + int r1, r2, r3; + unsigned int uimm; + signed int simm; + + /* separate tokens */ + n = 0; + p = strtok(line, " \t\n,"); + while (p != NULL) { + if (n == MAX_TOKENS) { + return msgs[0]; + } + tokens[n++] = p; + p = strtok(NULL, " \t\n,"); + } + if (n == 0) { + return msgs[1]; + } + /* lookup mnemonic */ + instr = lookupInstr(tokens[0]); + if (instr == NULL) { + return msgs[2]; + } + /* do processing according to format */ + switch (instr->format) { + case FORMAT_N: + /* no operands (but may get a constant operand) */ + if (n > 2) { + return msgs[4]; + } + if (n < 1) { + return msgs[5]; + } + if (n == 2) { + if (!asmNum(tokens[1], &uimm)) { + return msgs[7]; + } + } else { + uimm = 0; + } + result = ((Word) instr->opcode << 26) | + (uimm & MASK(26)); + break; + case FORMAT_RH: + /* one register and a half operand */ + if (n > 3) { + return msgs[4]; + } + if (n < 3) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmNum(tokens[2], &uimm)) { + return msgs[7]; + } + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 16) | + (uimm & MASK(16)); + break; + case FORMAT_RHH: + /* one register and a half operand */ + /* ATTENTION: high-order 16 bits encoded */ + if (n > 3) { + return msgs[4]; + } + if (n < 3) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmNum(tokens[2], &uimm)) { + return msgs[7]; + } + uimm >>= 16; + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 16) | + (uimm & MASK(16)); + break; + case FORMAT_RRH: + /* two registers and a half operand */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmNum(tokens[3], &uimm)) { + return msgs[7]; + } + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r1 << 16) | + (uimm & MASK(16)); + break; + case FORMAT_RRS: + /* two registers and a signed half operand */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmNum(tokens[3], (unsigned int *) &simm)) { + return msgs[7]; + } + if (simm >= (signed) (1 << 15) || + simm < - (signed) (1 << 15)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r1 << 16) | + (simm & MASK(16)); + break; + case FORMAT_RRR: + /* three register operands */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmReg(tokens[3], &r3)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r3 << 16) | + (r1 << 11); + break; + case FORMAT_RRX: + /* either FORMAT_RRR or FORMAT_RRH */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (*tokens[3] == '$') { + /* FORMAT_RRR */ + if (!asmReg(tokens[3], &r3)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r3 << 16) | + (r1 << 11); + } else { + /* FORMAT_RRH */ + if (!asmNum(tokens[3], &uimm)) { + return msgs[7]; + } + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = (((Word) instr->opcode + 1) << 26) | + (r2 << 21) | + (r1 << 16) | + (uimm & MASK(16)); + } + break; + case FORMAT_RRY: + /* either FORMAT_RRR or FORMAT_RRS */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (*tokens[3] == '$') { + /* FORMAT_RRR */ + if (!asmReg(tokens[3], &r3)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r3 << 16) | + (r1 << 11); + } else { + /* FORMAT_RRS */ + if (!asmNum(tokens[3], (unsigned int *) &simm)) { + return msgs[7]; + } + if (simm >= (signed) (1 << 15) || + simm < - (signed) (1 << 15)) { + return msgs[8]; + } + result = (((Word) instr->opcode + 1) << 26) | + (r2 << 21) | + (r1 << 16) | + (simm & MASK(16)); + } + break; + case FORMAT_RRB: + /* two registers and a 16 bit signed offset operand */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmNum(tokens[3], (unsigned int *) &simm)) { + return msgs[7]; + } + if ((simm & 0x00000003) != 0) { + return msgs[9]; + } + simm -= addr + 4; + simm /= 4; + if (simm >= (signed) (1 << 15) || + simm < - (signed) (1 << 15)) { + return msgs[10]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 21) | + (r2 << 16) | + (simm & MASK(16)); + break; + case FORMAT_J: + /* no registers and a 26 bit signed offset operand */ + if (n > 2) { + return msgs[4]; + } + if (n < 2) { + return msgs[5]; + } + if (!asmNum(tokens[1], (unsigned int *) &simm)) { + return msgs[7]; + } + if ((simm & 0x00000003) != 0) { + return msgs[9]; + } + simm -= addr + 4; + simm /= 4; + if (simm >= (signed) (1 << 25) || + simm < - (signed) (1 << 25)) { + return msgs[10]; + } + result = ((Word) instr->opcode << 26) | + (simm & MASK(26)); + break; + case FORMAT_JR: + /* one register operand */ + if (n > 2) { + return msgs[4]; + } + if (n < 2) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 21); + break; + default: + return msgs[3]; + } + /* line successfully assembled */ + *instrPtr = result; + return NULL; +} Index: monitor/monitor-digilent/monitor.map =================================================================== --- monitor/monitor-digilent/monitor.map (nonexistent) +++ monitor/monitor-digilent/monitor.map (revision 16) @@ -0,0 +1,105 @@ +_bbss BSS 0x00000000 +_bcode CODE 0x00000000 +_bdata DATA 0x00000000 +_ebss BSS 0x00000B70 +_ecode CODE 0x000072B0 +_edata DATA 0x00001A70 +addHist CODE 0x000053CC +asmInstr CODE 0x0000280C +boot CODE 0x0000421C +cin CODE 0x00000010 +cinchk CODE 0x0000000C +commands DATA 0x00000028 +cout CODE 0x00000018 +coutchk CODE 0x00000014 +cpuGetBreak CODE 0x000043FC +cpuGetPC CODE 0x00004354 +cpuGetPSW CODE 0x000043C0 +cpuGetReg CODE 0x0000437C +cpuResetBreak CODE 0x00004438 +cpuRun CODE 0x00004AA8 +cpuSetBreak CODE 0x00004410 +cpuSetPC CODE 0x00004368 +cpuSetPSW CODE 0x000043D4 +cpuSetReg CODE 0x00004398 +cpuStep CODE 0x000045AC +cpuTestBreak CODE 0x000043E8 +debugBreak CODE 0x000054AC +disasm CODE 0x00003820 +dskcap CODE 0x0000002C +dskio CODE 0x00000030 +dspinit CODE 0x00006BC4 +dspout CODE 0x00006C0C +dspoutchk CODE 0x00006C04 +exceptionToString CODE 0x0000444C +execCommand CODE 0x000024B0 +getLine CODE 0x00005064 +getTLB_HI CODE 0x000000E8 +getTLB_LO CODE 0x000000F8 +getchar CODE 0x00005BB4 +initInstrTable CODE 0x0000255C +instrCodeTbl BSS 0x0000009C +instrTbl DATA 0x00000F60 +kbdin CODE 0x00006840 +kbdinchk CODE 0x0000682C +kbdinit CODE 0x00006828 +load CODE 0x00003CB8 +lookupInstr CODE 0x00002680 +main CODE 0x00000320 +mmuGetEntryHi CODE 0x00004EF0 +mmuGetEntryLo CODE 0x00004F18 +mmuGetIndex CODE 0x00004EC8 +mmuGetTLB CODE 0x00004F40 +mmuReadByte CODE 0x00004E98 +mmuReadHalf CODE 0x00004E8C +mmuReadWord CODE 0x00004E80 +mmuSetEntryHi CODE 0x00004F04 +mmuSetEntryLo CODE 0x00004F2C +mmuSetIndex CODE 0x00004EDC +mmuSetTLB CODE 0x00005008 +mmuWriteByte CODE 0x00004EBC +mmuWriteHalf CODE 0x00004EB0 +mmuWriteWord CODE 0x00004EA4 +monitorReturn BSS 0x00000000 +numCommands DATA 0x000000F4 +printf CODE 0x00006740 +putchar CODE 0x00005BD8 +puts CODE 0x00005C14 +qsort CODE 0x00005B68 +resume CODE 0x000001C8 +saveState CODE 0x00000154 +sctcapctl CODE 0x00006F54 +sctcapser CODE 0x000070C4 +sctioctl CODE 0x00006F8C +sctioser CODE 0x00007198 +ser0in CODE 0x00006E98 +ser0inchk CODE 0x00006E84 +ser0out CODE 0x00006EC8 +ser0outchk CODE 0x00006EB4 +ser1in CODE 0x00006EFC +ser1inchk CODE 0x00006EE4 +ser1out CODE 0x00006F34 +ser1outchk CODE 0x00006F1C +serinit CODE 0x00006E80 +setTLB CODE 0x00000108 +sin CODE 0x00000020 +sinchk CODE 0x0000001C +sout CODE 0x00000028 +soutchk CODE 0x00000024 +sprintf CODE 0x000067E4 +strcat CODE 0x0000555C +strchr CODE 0x000055A8 +strcmp CODE 0x000054E8 +strcpy CODE 0x00005520 +strlen CODE 0x000054B0 +strtok CODE 0x000055D8 +strtoul CODE 0x000058AC +userContext BSS 0x00000004 +vprintf CODE 0x00006700 +vsprintf CODE 0x0000678C +xltbl1 CODE 0x000069C4 +xltbl2 CODE 0x00006AC4 + +CODE start 0xE0000000 size 0x000072B0 +DATA start 0xC3FFC000 size 0x00001A70 +BSS start 0xC3FFDA70 size 0x00000B70 Index: monitor/monitor-digilent/command.h =================================================================== --- monitor/monitor-digilent/command.h (nonexistent) +++ monitor/monitor-digilent/command.h (revision 16) @@ -0,0 +1,13 @@ +/* + * command.h -- command interpreter + */ + + +#ifndef _COMMAND_H_ +#define _COMMAND_H_ + + +void execCommand(char *line); + + +#endif /* _COMMAND_H_ */ Index: monitor/monitor-digilent/main.c =================================================================== --- monitor/monitor-digilent/main.c (nonexistent) +++ monitor/monitor-digilent/main.c (revision 16) @@ -0,0 +1,27 @@ +/* + * main.c -- the main program + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "command.h" +#include "getline.h" +#include "instr.h" +#include "cpu.h" + + +int main(void) { + char *line; + + printf("\n\nECO32 Machine Monitor 1.1\n\n"); + initInstrTable(); + cpuSetPC(0xC0000000); + while (1) { + line = getLine("ECO32 > "); + addHist(line); + execCommand(line); + } + return 0; +} Index: monitor/monitor-digilent/asm.h =================================================================== --- monitor/monitor-digilent/asm.h (nonexistent) +++ monitor/monitor-digilent/asm.h (revision 16) @@ -0,0 +1,13 @@ +/* + * asm.h -- assembler + */ + + +#ifndef _ASM_H_ +#define _ASM_H_ + + +char *asmInstr(char *line, Word addr, Word *instrPtr); + + +#endif /* _ASM_H_ */ Index: monitor/monitor-digilent/sctio-ser.s =================================================================== --- monitor/monitor-digilent/sctio-ser.s (nonexistent) +++ monitor/monitor-digilent/sctio-ser.s (revision 16) @@ -0,0 +1,200 @@ +; +; sctio-ser.s -- disk sector I/O for disk made available by serial interface +; + +;*************************************************************** + + .export sctcapser ; determine disk capacity + .export sctioser ; do disk I/O + + .import ser1in + .import ser1out + .import ser1inchk + .import puts + + ; constants for communication with disk server + .set SYN,0x16 ; to initiate the three-way handshake + .set ACK,0x06 ; acknowledgement for handshake + .set RESULT_OK,0x00 ; server successfully executed cmd + ; everything else means error + + .set WAIT_DELAY,800000 ; count for delay loop + +;*************************************************************** + + .code + .align 4 + +sctcapser: + sub $29,$29,16 + stw $16,$29,0 + stw $17,$29,4 + stw $18,$29,8 + stw $31,$29,12 + add $4,$0,trymsg ; say what we are doing + jal puts + add $18,$0,$0 ; capacity == 0 if disk not present + add $16,$0,10 ; 10 tries to get a connection +handshake1: + sub $16,$16,1 + add $4,$0,SYN + jal ser1out ; send SYN + add $17,$0,WAIT_DELAY ; wait for ACK +handshake2: + sub $17,$17,1 + jal ser1inchk + bne $2,$0,handshake3 + bne $17,$0,handshake2 + add $4,$0,timeoutmsg + jal puts + bne $16,$0,handshake1 + add $4,$0,frustratedmsg + jal puts + j sctcapx +handshake3: + jal ser1in + add $8,$0,ACK + bne $2,$8,sctcapx + ; we got an ACK so we return it + add $4,$0,ACK + jal ser1out + + ; ask it for its capacity + add $4,$0,'c' + jal ser1out ; request + jal ser1in ; first byte of response + bne $2,$0,sctcapx ; exit if error + + ; all is well and the server will give us the capacity + add $16,$0,4 ; 4 bytes to read +sctcap1: + sll $18,$18,8 + jal ser1in + or $18,$18,$2 ; most significant byte first + sub $16,$16,1 + bne $16,$0,sctcap1 + + ; return value is in $18 +sctcapx: + add $2,$0,$18 + ldw $16,$29,0 + ldw $17,$29,4 + ldw $18,$29,8 + ldw $31,$29,12 + add $29,$29,16 + jr $31 + + .data + .align 4 + +trymsg: + .byte "Trying to connect to disk server..." + .byte 0x0A, 0 + +timeoutmsg: + .byte "Request timed out..." + .byte 0x0A, 0 + +frustratedmsg: + .byte "Unable to establish connection to disk server." + .byte 0x0A, 0 + + .code + .align 4 + +sctioser: + sub $29,$29,24 + stw $16,$29,0 + stw $17,$29,4 + stw $18,$29,8 + stw $19,$29,12 + stw $20,$29,16 + stw $31,$29,20 + add $16,$0,$4 ; command + add $17,$0,$5 ; start at sector + add $8,$0,0xc0000000 + or $18,$8,$6 ; memory address (logicalized) + add $19,$0,$7 ; number of sectors + + ; switch over command + add $8,$0,'r' + beq $8,$16,sctior ; read + add $8,$0,'w' + beq $8,$16,sctiow ; write + ; unknown command + add $2,$0,1 ; value != 0 signifies error + j sctiox + + ; read from disk +sctior: +sctior1: ; loop over number of sectors + beq $19,$0,sctiorsuc ; successful return + sub $19,$19,1 + ; read a sector + add $4,$0,'r' + jal ser1out + ; send sector number + add $20,$0,32 ; 4 bytes +sctior2: + sub $20,$20,8 + slr $4,$17,$20 + and $4,$4,0xff + jal ser1out + bne $20,$0,sctior2 + add $17,$17,1 + ; get answer + jal ser1in + bne $2,$0,sctiox ; $2 != 0 so we use it as return code + ; read data + add $20,$0,512 +sctior3: + sub $20,$20,1 + jal ser1in + stb $2,$18,0 + add $18,$18,1 + bne $20,$0,sctior3 + j sctior1 +sctiorsuc: + add $2,$0,$0 + j sctiox + + ; write to disk +sctiow: +sctiow1: ; loop over number of sectors + beq $19,$0,sctiowsuc ; successful return + sub $19,$19,1 + ; write a sector + add $4,$0,'w' + jal ser1out + ; send sector number + add $20,$0,32 ; 4 bytes +sctiow2: + sub $20,$20,8 + slr $4,$17,$20 + and $4,$4,0xff + jal ser1out + bne $20,$0,sctiow2 + add $17,$17,1 + ; write data + add $20,$0,512 +sctiow3: + sub $20,$20,1 + ldbu $4,$18,0 + jal ser1out + add $18,$18,1 + bne $20,$0,sctiow3 + ; get answer + jal ser1in + bne $2,$0,sctiox + j sctiow1 +sctiowsuc: + add $2,$0,$0 +sctiox: + ldw $16,$29,0 + ldw $17,$29,4 + ldw $18,$29,8 + ldw $19,$29,12 + ldw $20,$29,16 + ldw $31,$29,20 + add $29,$29,24 + jr $31 Index: monitor/monitor-digilent/stdarg.h =================================================================== --- monitor/monitor-digilent/stdarg.h (nonexistent) +++ monitor/monitor-digilent/stdarg.h (revision 16) @@ -0,0 +1,41 @@ +/* + * stdarg.h -- variable argument lists + */ + + +#ifndef _STDARG_H_ +#define _STDARG_H_ + + +typedef char *va_list; + + +static float __va_arg_tmp; + + +#define va_start(list, start) \ + ((void)((list) = (sizeof(start)<4 ? \ + (char *)((int *)&(start)+1) : (char *)(&(start)+1)))) + +#define __va_arg(list, mode, n) \ + (__typecode(mode)==1 && sizeof(mode)==4 ? \ + (__va_arg_tmp = *(double *)(&(list += \ + ((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ + *(mode *)&__va_arg_tmp) : \ + *(mode *)(&(list += \ + ((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) + +#define _bigendian_va_arg(list, mode, n) \ + (sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ + sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ + __va_arg(list, mode, n)) + +#define va_end(list) ((void)0) + +#define va_arg(list, mode) \ + (sizeof(mode)==8 ? \ + *(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ + _bigendian_va_arg(list, mode, 3U)) + + +#endif /* _STDARG_H_ */ Index: monitor/monitor-digilent/common.h =================================================================== --- monitor/monitor-digilent/common.h (nonexistent) +++ monitor/monitor-digilent/common.h (revision 16) @@ -0,0 +1,27 @@ +/* + * common.h -- common definitions + */ + + +#ifndef _COMMON_H_ +#define _COMMON_H_ + + +#define PAGE_SHIFT 12 /* log2 of page size */ +#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ +#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ +#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ + + +typedef enum { false, true } Bool; /* truth values */ + + +typedef unsigned int Word; /* 32 bit quantities */ +typedef unsigned short Half; /* 16 bit quantities */ +typedef unsigned char Byte; /* 8 bit quantities */ + + +#define NULL ((void *) 0) + + +#endif /* _COMMON_H_ */ Index: monitor/kbdtbls/Makefile =================================================================== --- monitor/kbdtbls/Makefile (nonexistent) +++ monitor/kbdtbls/Makefile (revision 16) @@ -0,0 +1,18 @@ +# +# Makefile to construct the keyboard mapping tables +# + +.PHONY: all install clean + +all: kbdtbls.s + +install: kbdtbls.s + +kbdtbls.s: mkkbdtbls + ./mkkbdtbls > kbdtbls.s + +mkkbdtbls: mkkbdtbls.c + gcc -m32 -g -Wall -o mkkbdtbls mkkbdtbls.c + +clean: + rm -f *~ mkkbdtbls kbdtbls.s Index: monitor/kbdtbls/mkkbdtbls.c =================================================================== --- monitor/kbdtbls/mkkbdtbls.c (nonexistent) +++ monitor/kbdtbls/mkkbdtbls.c (revision 16) @@ -0,0 +1,171 @@ +/* + * mkkbdtbls.c -- construct keyboard translation tables + */ + + +#include +#include +#include + + +typedef struct { + unsigned char ascii; + unsigned char key; +} Entry; + + +Entry tbl1[] = { + { 0x1B, 0x76 }, + { '1', 0x16 }, + { '2', 0x1E }, + { '3', 0x26 }, + { '4', 0x25 }, + { '5', 0x2E }, + { '6', 0x36 }, + { '7', 0x3D }, + { '8', 0x3E }, + { '9', 0x46 }, + { '0', 0x45 }, + { '^', 0x0E }, + { 0x08, 0x66 }, + { 0x09, 0x0D }, + { 'q', 0x15 }, + { 'w', 0x1D }, + { 'e', 0x24 }, + { 'r', 0x2D }, + { 't', 0x2C }, + { 'z', 0x35 }, + { 'u', 0x3C }, + { 'i', 0x43 }, + { 'o', 0x44 }, + { 'p', 0x4D }, + { '\r', 0x5A }, + { ' ', 0x29 }, + { 'a', 0x1C }, + { 's', 0x1B }, + { 'd', 0x23 }, + { 'f', 0x2B }, + { 'g', 0x34 }, + { 'h', 0x33 }, + { 'j', 0x3B }, + { 'k', 0x42 }, + { 'l', 0x4B }, + { 'y', 0x1A }, + { 'x', 0x22 }, + { 'c', 0x21 }, + { 'v', 0x2A }, + { 'b', 0x32 }, + { 'n', 0x31 }, + { 'm', 0x3A }, + { ',', 0x41 }, + { '.', 0x49 }, + { '-', 0x4A }, + { '+', 0x5B }, + { '#', 0x5D }, + { '<', 0x61 }, +}; + + +Entry tbl2[] = { + { 0x1B, 0x76 }, + { '!', 0x16 }, + { '"', 0x1E }, + { '3', 0x26 }, + { '$', 0x25 }, + { '%', 0x2E }, + { '&', 0x36 }, + { '/', 0x3D }, + { '(', 0x3E }, + { ')', 0x46 }, + { '=', 0x45 }, + { '^', 0x0E }, + { 0x08, 0x66 }, + { 0x09, 0x0D }, + { 'Q', 0x15 }, + { 'W', 0x1D }, + { 'E', 0x24 }, + { 'R', 0x2D }, + { 'T', 0x2C }, + { 'Z', 0x35 }, + { 'U', 0x3C }, + { 'I', 0x43 }, + { 'O', 0x44 }, + { 'P', 0x4D }, + { '\r', 0x5A }, + { ' ', 0x29 }, + { 'A', 0x1C }, + { 'S', 0x1B }, + { 'D', 0x23 }, + { 'F', 0x2B }, + { 'G', 0x34 }, + { 'H', 0x33 }, + { 'J', 0x3B }, + { 'K', 0x42 }, + { 'L', 0x4B }, + { 'Y', 0x1A }, + { 'X', 0x22 }, + { 'C', 0x21 }, + { 'V', 0x2A }, + { 'B', 0x32 }, + { 'N', 0x31 }, + { 'M', 0x3A }, + { ';', 0x41 }, + { ':', 0x49 }, + { '_', 0x4A }, + { '*', 0x5B }, + { '\'', 0x5D }, + { '>', 0x61 }, +}; + + +int main(void) { + unsigned char codes[256]; + int i, j; + + for (i = 0; i < 256; i++) { + codes[i] = '\0'; + } + for (i = 0; i < sizeof(tbl1)/sizeof(tbl1[0]); i++) { + codes[tbl1[i].key] = tbl1[i].ascii; + } + printf(";\n"); + printf("; keyboard code tables\n"); + printf(";\n"); + printf("\n"); + printf("\t.export\txltbl1\n"); + printf("\t.export\txltbl2\n"); + printf("\n"); + printf("\t.code\n"); + printf("\t.align\t4\n"); + printf("\n"); + printf("xltbl1:\n"); + for (i = 0; i < 32; i++) { + printf("\t.byte\t"); + for (j = 0; j < 8; j++) { + printf("0x%02X", codes[i * 8 + j]); + if (j < 7) { + printf(", "); + } + } + printf("\n"); + } + printf("\n"); + for (i = 0; i < 256; i++) { + codes[i] = '\0'; + } + for (i = 0; i < sizeof(tbl2)/sizeof(tbl2[0]); i++) { + codes[tbl2[i].key] = tbl2[i].ascii; + } + printf("xltbl2:\n"); + for (i = 0; i < 32; i++) { + printf("\t.byte\t"); + for (j = 0; j < 8; j++) { + printf("0x%02X", codes[i * 8 + j]); + if (j < 7) { + printf(", "); + } + } + printf("\n"); + } + return 0; +} Index: monitor/monitor/mmu.c =================================================================== --- monitor/monitor/mmu.c (nonexistent) +++ monitor/monitor/mmu.c (revision 16) @@ -0,0 +1,104 @@ +/* + * mmu.c -- memory and TLB access + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "mmu.h" +#include "start.h" + + +static Word tlbIndex; +static Word tlbEntryHi; +static Word tlbEntryLo; + + +Word mmuReadWord(Word vAddr) { + return *(Word *)vAddr; +} + + +Half mmuReadHalf(Word vAddr) { + return *(Half *)vAddr; +} + + +Byte mmuReadByte(Word vAddr) { + return *(Byte *)vAddr; +} + + +void mmuWriteWord(Word vAddr, Word data) { + *(Word *)vAddr = data; +} + + +void mmuWriteHalf(Word vAddr, Half data) { + *(Half *)vAddr = data; +} + + +void mmuWriteByte(Word vAddr, Byte data) { + *(Byte *)vAddr = data; +} + + +Word mmuGetIndex(void) { + return tlbIndex; +} + + +void mmuSetIndex(Word value) { + tlbIndex = value; +} + + +Word mmuGetEntryHi(void) { + return tlbEntryHi; +} + + +void mmuSetEntryHi(Word value) { + tlbEntryHi = value; +} + + +Word mmuGetEntryLo(void) { + return tlbEntryLo; +} + + +void mmuSetEntryLo(Word value) { + tlbEntryLo = value; +} + + +TLB_Entry mmuGetTLB(int index) { + Word hi; + Word lo; + TLB_Entry result; + + hi = getTLB_HI(index); + lo = getTLB_LO(index); + result.page = hi & PAGE_MASK; + result.frame = lo & PAGE_MASK; + result.write = (lo & TLB_WRITE) ? true : false; + result.valid = (lo & TLB_VALID) ? true : false; + return result; +} + + +void mmuSetTLB(int index, TLB_Entry tlbEntry) { + Word flags; + + flags = 0; + if (tlbEntry.write) { + flags |= TLB_WRITE; + } + if (tlbEntry.valid) { + flags |= TLB_VALID; + } + setTLB(index, tlbEntry.page, tlbEntry.frame | flags); +} Index: monitor/monitor/instr.c =================================================================== --- monitor/monitor/instr.c (nonexistent) +++ monitor/monitor/instr.c (revision 16) @@ -0,0 +1,115 @@ +/* + * instr.c -- instruction encoding + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "instr.h" + + +/* + * This is the ECO32 machine instruction set. + * The table below needs no particular order + * and may have gaps in the instruction encoding. + */ +Instr instrTbl[] = { + { "add", FORMAT_RRY, OP_ADD }, + { "sub", FORMAT_RRY, OP_SUB }, + { "mul", FORMAT_RRY, OP_MUL }, + { "mulu", FORMAT_RRX, OP_MULU }, + { "div", FORMAT_RRY, OP_DIV }, + { "divu", FORMAT_RRX, OP_DIVU }, + { "rem", FORMAT_RRY, OP_REM }, + { "remu", FORMAT_RRX, OP_REMU }, + { "and", FORMAT_RRX, OP_AND }, + { "or", FORMAT_RRX, OP_OR }, + { "xor", FORMAT_RRX, OP_XOR }, + { "xnor", FORMAT_RRX, OP_XNOR }, + { "sll", FORMAT_RRX, OP_SLL }, + { "slr", FORMAT_RRX, OP_SLR }, + { "sar", FORMAT_RRX, OP_SAR }, + { "ldhi", FORMAT_RHH, OP_LDHI }, + { "beq", FORMAT_RRB, OP_BEQ }, + { "bne", FORMAT_RRB, OP_BNE }, + { "ble", FORMAT_RRB, OP_BLE }, + { "bleu", FORMAT_RRB, OP_BLEU }, + { "blt", FORMAT_RRB, OP_BLT }, + { "bltu", FORMAT_RRB, OP_BLTU }, + { "bge", FORMAT_RRB, OP_BGE }, + { "bgeu", FORMAT_RRB, OP_BGEU }, + { "bgt", FORMAT_RRB, OP_BGT }, + { "bgtu", FORMAT_RRB, OP_BGTU }, + { "j", FORMAT_J, OP_J }, + { "jr", FORMAT_JR, OP_JR }, + { "jal", FORMAT_J, OP_JAL }, + { "jalr", FORMAT_JR, OP_JALR }, + { "trap", FORMAT_N, OP_TRAP }, + { "rfx", FORMAT_N, OP_RFX }, + { "ldw", FORMAT_RRS, OP_LDW }, + { "ldh", FORMAT_RRS, OP_LDH }, + { "ldhu", FORMAT_RRS, OP_LDHU }, + { "ldb", FORMAT_RRS, OP_LDB }, + { "ldbu", FORMAT_RRS, OP_LDBU }, + { "stw", FORMAT_RRS, OP_STW }, + { "sth", FORMAT_RRS, OP_STH }, + { "stb", FORMAT_RRS, OP_STB }, + { "mvfs", FORMAT_RH, OP_MVFS }, + { "mvts", FORMAT_RH, OP_MVTS }, + { "tbs", FORMAT_N, OP_TBS }, + { "tbwr", FORMAT_N, OP_TBWR }, + { "tbri", FORMAT_N, OP_TBRI }, + { "tbwi", FORMAT_N, OP_TBWI } +}; + + +Instr *instrCodeTbl[64]; + + +static int instrCompare(const void *instr1, const void *instr2) { + return strcmp(((Instr *) instr1)->name, ((Instr *) instr2)->name); +} + + +void initInstrTable(void) { + int i; + + /* first sort instruction table alphabetically */ + qsort(instrTbl, sizeof(instrTbl)/sizeof(instrTbl[0]), + sizeof(instrTbl[0]), instrCompare); + /* then initialize instruction code table */ + for (i = 0; i < 64; i++) { + instrCodeTbl[i] = NULL; + } + for (i = 0; i < sizeof(instrTbl)/sizeof(instrTbl[0]); i++) { + instrCodeTbl[instrTbl[i].opcode] = &instrTbl[i]; + if (instrTbl[i].format == FORMAT_RRX || + instrTbl[i].format == FORMAT_RRY) { + /* enter the immediate variant of this instruction also */ + instrCodeTbl[instrTbl[i].opcode + 1] = &instrTbl[i]; + } + } +} + + +Instr *lookupInstr(char *name) { + int lo, hi, tst; + int res; + + lo = 0; + hi = sizeof(instrTbl) / sizeof(instrTbl[0]) - 1; + while (lo <= hi) { + tst = (lo + hi) / 2; + res = strcmp(instrTbl[tst].name, name); + if (res == 0) { + return &instrTbl[tst]; + } + if (res < 0) { + lo = tst + 1; + } else { + hi = tst - 1; + } + } + return NULL; +} Index: monitor/monitor/serial.s =================================================================== --- monitor/monitor/serial.s (nonexistent) +++ monitor/monitor/serial.s (revision 16) @@ -0,0 +1,98 @@ +; +; serial.s -- the serial line interface +; + +;*************************************************************** + + .set ser0base,0xF0300000 ; serial line 0 base address + .set ser1base,0xF0300010 ; serial line 1 base address + + .export serinit ; initialize serial interface + + .export ser0inchk ; line 0 input check + .export ser0in ; line 0 input + .export ser0outchk ; line 0 output check + .export ser0out ; line 0 output + + .export ser1inchk ; line 1 input check + .export ser1in ; line 1 input + .export ser1outchk ; line 1 output check + .export ser1out ; line 1 output + +;*************************************************************** + + .code + .align 4 + +serinit: + jr $31 + +;*************************************************************** + + .code + .align 4 + +ser0inchk: + add $8,$0,ser0base + ldw $2,$8,0 + and $2,$2,1 + jr $31 + +ser0in: + add $8,$0,ser0base +ser0in1: + ldw $9,$8,0 + and $9,$9,1 + beq $9,$0,ser0in1 + ldw $2,$8,4 + jr $31 + +ser0outchk: + add $8,$0,ser0base + ldw $2,$8,8 + and $2,$2,1 + jr $31 + +ser0out: + add $8,$0,ser0base +ser0out1: + ldw $9,$8,8 + and $9,$9,1 + beq $9,$0,ser0out1 + stw $4,$8,12 + jr $31 + +;*************************************************************** + + .code + .align 4 + +ser1inchk: + add $8,$0,ser1base + ldw $2,$8,0 + and $2,$2,1 + jr $31 + +ser1in: + add $8,$0,ser1base +ser1in1: + ldw $9,$8,0 + and $9,$9,1 + beq $9,$0,ser1in1 + ldw $2,$8,4 + jr $31 + +ser1outchk: + add $8,$0,ser1base + ldw $2,$8,8 + and $2,$2,1 + jr $31 + +ser1out: + add $8,$0,ser1base +ser1out1: + ldw $9,$8,8 + and $9,$9,1 + beq $9,$0,ser1out1 + stw $4,$8,12 + jr $31 Index: monitor/monitor/start.h =================================================================== --- monitor/monitor/start.h (nonexistent) +++ monitor/monitor/start.h (revision 16) @@ -0,0 +1,57 @@ +/* + * start.h -- ECO32 ROM monitor startup and support routines + */ + + +#ifndef _START_H_ +#define _START_H_ + + +typedef struct { + Word reg[32]; /* general purpose registers */ + Word psw; /* PSW */ + Word tlbIndex; /* TLB index register */ + Word tlbHi; /* TLB EntryHi register */ + Word tlbLo; /* TLB EntryLo register */ +} UserContext; + +typedef struct { + Word r31; /* return address */ + Word r29; /* stack pointer */ + Word r16; /* local variable */ + Word r17; /* local variable */ + Word r18; /* local variable */ + Word r19; /* local variable */ + Word r20; /* local variable */ + Word r21; /* local variable */ + Word r22; /* local variable */ + Word r23; /* local variable */ +} MonitorState; + + +int cinchk(void); +int cin(void); +int coutchk(void); +void cout(char c); + +int sinchk(void); +int sin(void); +int soutchk(void); +void sout(char c); + +int dskcap(int dskno); +int dskio(int dskno, char cmd, int sct, Word addr, int nscts); + +Word getTLB_HI(int index); +Word getTLB_LO(int index); +void setTLB(int index, Word entryHi, Word entryLo); + +Bool saveState(MonitorState *msp); + +extern MonitorState *monitorReturn; +extern UserContext userContext; + +void resume(void); + + +#endif /* _START_H_ */ Index: monitor/monitor/boot.c =================================================================== --- monitor/monitor/boot.c (nonexistent) +++ monitor/monitor/boot.c (revision 16) @@ -0,0 +1,47 @@ +/* + * boot.c -- bootstrap from disk + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "boot.h" +#include "cpu.h" +#include "mmu.h" +#include "start.h" + + +void boot(int dskno) { + Word capacity; + Byte sig1, sig2; + + capacity = dskcap(dskno); + if (capacity == 0) { + printf("Disk not found!\n"); + return; + } + printf("Disk with 0x%08X sectors found, booting...\n", capacity); + if (dskio(dskno, 'r', 0, PHYS_BOOT, 1) != 0) { + printf("Disk error!\n"); + return; + } + sig1 = mmuReadByte(VIRT_BOOT + 512 - 2); + sig2 = mmuReadByte(VIRT_BOOT + 512 - 1); + if (sig1 != 0x55 || sig2 != 0xAA) { + printf("MBR signature missing!\n"); + return; + } + /* + * Boot convention: + * $16 disk number of boot disk + * $17 start sector number of disk or partition to boot + * $18 total number of sectors of disk or partition to boot + */ + cpuSetReg(16, dskno); + cpuSetReg(17, 0); + cpuSetReg(18, capacity); + cpuSetReg(29, TOS_BOOT); + cpuSetPC(VIRT_BOOT); + cpuRun(); +} Index: monitor/monitor/mmu.h =================================================================== --- monitor/monitor/mmu.h (nonexistent) +++ monitor/monitor/mmu.h (revision 16) @@ -0,0 +1,45 @@ +/* + * mmu.h -- memory and TLB access + */ + + +#ifndef _MMU_H_ +#define _MMU_H_ + + +#define TLB_SHFT 5 /* log2 of number of TLB entries */ +#define TLB_SIZE (1 << TLB_SHFT) /* total number of TLB entries */ +#define TLB_MASK (TLB_SIZE - 1) /* mask for number of TLB entries */ +#define TLB_FIXED 4 /* number of fixed TLB entries */ + +#define TLB_WRITE (1 << 1) /* write bit in EntryLo */ +#define TLB_VALID (1 << 0) /* valid bit in EntryLo */ + + +typedef struct { + Word page; /* 20 high-order bits of virtual address */ + Word frame; /* 20 high-order bits of physical address */ + Bool write; /* must be true to allow writing to the page */ + Bool valid; /* must be true for the entry to be valid */ +} TLB_Entry; + + +Word mmuReadWord(Word vAddr); +Half mmuReadHalf(Word vAddr); +Byte mmuReadByte(Word vAddr); +void mmuWriteWord(Word vAddr, Word data); +void mmuWriteHalf(Word vAddr, Half data); +void mmuWriteByte(Word vAddr, Byte data); + +Word mmuGetIndex(void); +void mmuSetIndex(Word value); +Word mmuGetEntryHi(void); +void mmuSetEntryHi(Word value); +Word mmuGetEntryLo(void); +void mmuSetEntryLo(Word Value); + +TLB_Entry mmuGetTLB(int index); +void mmuSetTLB(int index, TLB_Entry tlbEntry); + + +#endif /* _MMU_H_ */ Index: monitor/monitor/instr.h =================================================================== --- monitor/monitor/instr.h (nonexistent) +++ monitor/monitor/instr.h (revision 16) @@ -0,0 +1,125 @@ +/* + * instr.h -- instruction encoding + */ + + +#ifndef _INSTR_H_ +#define _INSTR_H_ + + +#define FORMAT_N 0 /* no operands */ +#define FORMAT_RH 1 /* one register and a half operand */ +#define FORMAT_RHH 2 /* one register and a half operand */ + /* ATTENTION: high-order 16 bits encoded */ +#define FORMAT_RRH 3 /* two registers and a half operand */ +#define FORMAT_RRS 4 /* two registers and a signed half operand */ +#define FORMAT_RRR 5 /* three register operands */ +#define FORMAT_RRX 6 /* either FORMAT_RRR or FORMAT_RRH */ +#define FORMAT_RRY 7 /* either FORMAT_RRR or FORMAT_RRS */ +#define FORMAT_RRB 8 /* two registers and a 16 bit signed + offset operand */ +#define FORMAT_J 9 /* no registers and a 26 bit signed + offset operand */ +#define FORMAT_JR 10 /* one register operand */ + + +#define MASK(n) ((((Word) 1) << n) - 1) +#define SIGN(n) (((Word) 1) << (n - 1)) +#define ZEXT16(x) (((Word) (x)) & MASK(16)) +#define SEXT16(x) (((Word) (x)) & SIGN(16) ? \ + (((Word) (x)) | ~MASK(16)) : \ + (((Word) (x)) & MASK(16))) +#define SEXT26(x) (((Word) (x)) & SIGN(26) ? \ + (((Word) (x)) | ~MASK(26)) : \ + (((Word) (x)) & MASK(26))) + + +#define OP_ADD 0x00 +#define OP_ADDI 0x01 +#define OP_SUB 0x02 +#define OP_SUBI 0x03 + +#define OP_MUL 0x04 +#define OP_MULI 0x05 +#define OP_MULU 0x06 +#define OP_MULUI 0x07 +#define OP_DIV 0x08 +#define OP_DIVI 0x09 +#define OP_DIVU 0x0A +#define OP_DIVUI 0x0B +#define OP_REM 0x0C +#define OP_REMI 0x0D +#define OP_REMU 0x0E +#define OP_REMUI 0x0F + +#define OP_AND 0x10 +#define OP_ANDI 0x11 +#define OP_OR 0x12 +#define OP_ORI 0x13 +#define OP_XOR 0x14 +#define OP_XORI 0x15 +#define OP_XNOR 0x16 +#define OP_XNORI 0x17 + +#define OP_SLL 0x18 +#define OP_SLLI 0x19 +#define OP_SLR 0x1A +#define OP_SLRI 0x1B +#define OP_SAR 0x1C +#define OP_SARI 0x1D + +#define OP_LDHI 0x1F + +#define OP_BEQ 0x20 +#define OP_BNE 0x21 +#define OP_BLE 0x22 +#define OP_BLEU 0x23 +#define OP_BLT 0x24 +#define OP_BLTU 0x25 +#define OP_BGE 0x26 +#define OP_BGEU 0x27 +#define OP_BGT 0x28 +#define OP_BGTU 0x29 + +#define OP_J 0x2A +#define OP_JR 0x2B +#define OP_JAL 0x2C +#define OP_JALR 0x2D + +#define OP_TRAP 0x2E +#define OP_RFX 0x2F + +#define OP_LDW 0x30 +#define OP_LDH 0x31 +#define OP_LDHU 0x32 +#define OP_LDB 0x33 +#define OP_LDBU 0x34 + +#define OP_STW 0x35 +#define OP_STH 0x36 +#define OP_STB 0x37 + +#define OP_MVFS 0x38 +#define OP_MVTS 0x39 +#define OP_TBS 0x3A +#define OP_TBWR 0x3B +#define OP_TBRI 0x3C +#define OP_TBWI 0x3D + + +typedef struct { + char *name; + int format; + Byte opcode; +} Instr; + + +extern Instr instrTbl[]; +extern Instr *instrCodeTbl[]; + + +void initInstrTable(void); +Instr *lookupInstr(char *name); + + +#endif /* _INSTR_H_ */ Index: monitor/monitor/boot.h =================================================================== --- monitor/monitor/boot.h (nonexistent) +++ monitor/monitor/boot.h (revision 16) @@ -0,0 +1,18 @@ +/* + * boot.h -- bootstrap from disk + */ + + +#ifndef _BOOT_H_ +#define _BOOT_H_ + + +#define PHYS_BOOT 0x00000000 /* where to load the bootstrap */ +#define VIRT_BOOT 0xC0000000 /* where to start the bootstrap */ +#define TOS_BOOT 0xC0001000 /* top of stack for bootstrap */ + + +void boot(int dskno); + + +#endif /* _BOOT_H_ */ Index: monitor/monitor/start.s =================================================================== --- monitor/monitor/start.s (nonexistent) +++ monitor/monitor/start.s (revision 16) @@ -0,0 +1,389 @@ +; +; start.s -- ECO32 ROM monitor startup and support routines +; + + .set dmapaddr,0xC0000000 ; base of directly mapped addresses + .set stacktop,0xC0400000 ; monitor stack is at top of memory + + .set PSW,0 ; reg # of PSW + .set TLB_INDEX,1 ; reg # of TLB Index + .set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi + .set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo + .set TLB_ENTRIES,32 ; number of TLB entries + + .set USER_CONTEXT_SIZE,36*4 ; size of user context + +;*************************************************************** + + .import _ecode + .import _edata + .import _ebss + + .import kbdinit + .import kbdinchk + .import kbdin + + .import dspinit + .import dspoutchk + .import dspout + + .import serinit + .import ser0inchk + .import ser0in + .import ser0outchk + .import ser0out + + .import sctcapctl + .import sctioctl + .import sctcapser + .import sctioser + + .import main + + .export _bcode + .export _bdata + .export _bbss + + .export cinchk + .export cin + .export coutchk + .export cout + .export sinchk + .export sin + .export soutchk + .export sout + .export dskcap + .export dskio + + .export getTLB_HI + .export getTLB_LO + .export setTLB + + .export saveState + .export monitorReturn + + .import userContext + .export resume + +;*************************************************************** + + .code +_bcode: + + .data +_bdata: + + .bss +_bbss: + +;*************************************************************** + + .code + .align 4 + +reset: + j start + +interrupt: + j isr + +userMiss: + j umsr + +;*************************************************************** + + .code + .align 4 + +cinchk: +; j kbdinchk + j ser0inchk + +cin: +; j kbdin + j ser0in + +coutchk: +; j dspoutchk + j ser0outchk + +cout: +; j dspout + j ser0out + +sinchk: + j ser0inchk + +sin: + j ser0in + +soutchk: + j ser0outchk + +sout: + j ser0out + +dskcap: + j dcap + +dskio: + j dio + +;*************************************************************** + + .code + .align 4 + +start: + ; force CPU into a defined state + mvts $0,PSW ; disable interrupts and user mode + + ; initialize TLB + mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries + add $8,$0,dmapaddr ; by impossible virtual page number + add $9,$0,$0 + add $10,$0,TLB_ENTRIES +tlbloop: + mvts $8,TLB_ENTRY_HI + mvts $9,TLB_INDEX + tbwi + add $8,$8,0x1000 ; all entries must be different + add $9,$9,1 + bne $9,$10,tlbloop + + ; copy data segment + add $10,$0,_bdata ; lowest dst addr to be written to + add $8,$0,_edata ; one above the top dst addr + sub $9,$8,$10 ; $9 = size of data segment + add $9,$9,_ecode ; data is waiting right after code + j cpytest +cpyloop: + ldw $11,$9,0 ; src addr in $9 + stw $11,$8,0 ; dst addr in $8 +cpytest: + sub $8,$8,4 ; downward + sub $9,$9,4 + bgeu $8,$10,cpyloop + + ; clear bss segment + add $8,$0,_bbss ; start with first word of bss + add $9,$0,_ebss ; this is one above the top + j clrtest +clrloop: + stw $0,$8,0 ; dst addr in $8 + add $8,$8,4 ; upward +clrtest: + bltu $8,$9,clrloop + + ; now do some useful work + add $29,$0,stacktop ; setup monitor stack +; jal dspinit ; init display +; jal kbdinit ; init keyboard + jal serinit ; init serial interface + jal main ; enter command loop + + ; main should never return + j start ; just to be sure... + +;*************************************************************** + + ; Word getTLB_HI(int index) +getTLB_HI: + mvts $4,TLB_INDEX + tbri + mvfs $2,TLB_ENTRY_HI + jr $31 + + ; Word getTLB_LO(int index) +getTLB_LO: + mvts $4,TLB_INDEX + tbri + mvfs $2,TLB_ENTRY_LO + jr $31 + + ; void setTLB(int index, Word entryHi, Word entryLo) +setTLB: + mvts $4,TLB_INDEX + mvts $5,TLB_ENTRY_HI + mvts $6,TLB_ENTRY_LO + tbwi + jr $31 + +;*************************************************************** + + ; int dskcap(int dskno) +dcap: + bne $4,$0,dcapser + j sctcapctl +dcapser: + j sctcapser + + ; int dskio(int dskno, char cmd, int sct, Word addr, int nscts) +dio: + bne $4,$0,dioser + add $4,$5,$0 + add $5,$6,$0 + add $6,$7,$0 + ldw $7,$29,16 + j sctioctl +dioser: + add $4,$5,$0 + add $5,$6,$0 + add $6,$7,$0 + ldw $7,$29,16 + j sctioser + +;*************************************************************** + + .code + .align 4 + + ; Bool saveState(MonitorState *msp) + ; always return 'true' here +saveState: + stw $31,$4,0*4 ; return address + stw $29,$4,1*4 ; stack pointer + stw $16,$4,2*4 ; local variables + stw $17,$4,3*4 + stw $18,$4,4*4 + stw $19,$4,5*4 + stw $20,$4,6*4 + stw $21,$4,7*4 + stw $22,$4,8*4 + stw $23,$4,9*4 + add $2,$0,1 + jr $31 + + ; load state when re-entering monitor + ; this appears as if returning from saveState + ; but the return value is 'false' here +loadState: + ldw $8,$0,monitorReturn + beq $8,$0,loadState ; fatal error: monitor state lost + ldw $31,$8,0*4 ; return address + ldw $29,$8,1*4 ; stack pointer + ldw $16,$8,2*4 ; local variables + ldw $17,$8,3*4 + ldw $18,$8,4*4 + ldw $19,$8,5*4 + ldw $20,$8,6*4 + ldw $21,$8,7*4 + ldw $22,$8,8*4 + ldw $23,$8,9*4 + add $2,$0,0 + jr $31 + + .bss + .align 4 + + ; extern MonitorState *monitorReturn +monitorReturn: + .space 4 + + ; extern UserContext userContext +userContext: + .space USER_CONTEXT_SIZE + +;*************************************************************** + + .code + .align 4 + + ; void resume(void) + ; use userContext to load state +resume: + mvts $0,PSW + add $28,$0,userContext + .nosyn + ldw $8,$28,33*4 ; tlbIndex + mvts $8,TLB_INDEX + ldw $8,$28,34*4 ; tlbWntryHi + mvts $8,TLB_ENTRY_HI + ldw $8,$28,35*4 ; tlbEntryLo + mvts $8,TLB_ENTRY_LO + ;ldw $0,$28,0*4 ; registers + ldw $1,$28,1*4 + ldw $2,$28,2*4 + ldw $3,$28,3*4 + ldw $4,$28,4*4 + ldw $5,$28,5*4 + ldw $6,$28,6*4 + ldw $7,$28,7*4 + ldw $8,$28,8*4 + ldw $9,$28,9*4 + ldw $10,$28,10*4 + ldw $11,$28,11*4 + ldw $12,$28,12*4 + ldw $13,$28,13*4 + ldw $14,$28,14*4 + ldw $15,$28,15*4 + ldw $16,$28,16*4 + ldw $17,$28,17*4 + ldw $18,$28,18*4 + ldw $19,$28,19*4 + ldw $20,$28,20*4 + ldw $21,$28,21*4 + ldw $22,$28,22*4 + ldw $23,$28,23*4 + ldw $24,$28,24*4 + ldw $25,$28,25*4 + ldw $26,$28,26*4 + ldw $27,$28,27*4 + ;ldw $28,$28,28*4 + ldw $29,$28,29*4 + ldw $30,$28,30*4 + ldw $31,$28,31*4 + ldw $28,$28,32*4 ; psw + mvts $28,PSW + rfx + .syn + + ; interrupt entry + ; use userContext to store state +isr: +umsr: + .nosyn + ldhi $28,userContext + or $28,$28,userContext + stw $0,$28,0*4 ; registers + stw $1,$28,1*4 + stw $2,$28,2*4 + stw $3,$28,3*4 + stw $4,$28,4*4 + stw $5,$28,5*4 + stw $6,$28,6*4 + stw $7,$28,7*4 + stw $8,$28,8*4 + stw $9,$28,9*4 + stw $10,$28,10*4 + stw $11,$28,11*4 + stw $12,$28,12*4 + stw $13,$28,13*4 + stw $14,$28,14*4 + stw $15,$28,15*4 + stw $16,$28,16*4 + stw $17,$28,17*4 + stw $18,$28,18*4 + stw $19,$28,19*4 + stw $20,$28,20*4 + stw $21,$28,21*4 + stw $22,$28,22*4 + stw $23,$28,23*4 + stw $24,$28,24*4 + stw $25,$28,25*4 + stw $26,$28,26*4 + stw $27,$28,27*4 + stw $28,$28,28*4 + stw $29,$28,29*4 + stw $30,$28,30*4 + stw $31,$28,31*4 + mvfs $8,PSW + stw $8,$28,32*4 ; psw + mvfs $8,TLB_INDEX + stw $8,$28,33*4 ; tlbIndex + mvfs $8,TLB_ENTRY_HI + stw $8,$28,34*4 ; tlbEntryHi + mvfs $8,TLB_ENTRY_LO + stw $8,$28,35*4 ; tlbEntryLo + .syn + j loadState Index: monitor/monitor/command.c =================================================================== --- monitor/monitor/command.c (nonexistent) +++ monitor/monitor/command.c (revision 16) @@ -0,0 +1,864 @@ +/* + * command.c -- command interpreter + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "getline.h" +#include "command.h" +#include "asm.h" +#include "disasm.h" +#include "boot.h" +#include "cpu.h" +#include "mmu.h" +#include "start.h" + + +#define MAX_TOKENS 10 + + +typedef struct { + char *name; + void (*hlpProc)(void); + void (*cmdProc)(char *tokens[], int n); +} Command; + +extern Command commands[]; +extern int numCommands; + + +static void help(void) { + printf("valid commands are:\n"); + printf(" help get help\n"); + printf(" + add and subtract\n"); + printf(" a assemble\n"); + printf(" u unassemble\n"); + printf(" b set/reset breakpoint\n"); + printf(" c continue from breakpoint\n"); + printf(" s single-step\n"); + printf(" @ show/set PC\n"); + printf(" p show/set PSW\n"); + printf(" r show/set register\n"); + printf(" d dump memory\n"); + printf(" mw show/set memory word\n"); + printf(" mh show/set memory halfword\n"); + printf(" mb show/set memory byte\n"); + printf(" t show/set TLB contents\n"); + printf(" boot bootstrap from disk\n"); + printf("type 'help ' to get help for \n"); +} + + +static void help00(void) { + printf(" help show a list of commands\n"); + printf(" help show help for \n"); +} + + +static void help01(void) { + printf(" + add and subtract and \n"); +} + + +static void help02(void) { + printf(" a assemble starting at PC\n"); + printf(" a assemble starting at \n"); +} + + +static void help03(void) { + printf(" u unassemble 16 instrs starting at PC\n"); + printf(" u unassemble 16 instrs starting at \n"); + printf(" u unassemble instrs starting at \n"); +} + + +static void help04(void) { + printf(" b reset break\n"); + printf(" b set break at \n"); +} + + +static void help05(void) { + printf(" c continue execution\n"); + printf(" c continue execution times\n"); +} + + +static void help06(void) { + printf(" s single-step one instruction\n"); + printf(" s single-step instructions\n"); +} + + +static void help07(void) { + printf(" @ show PC\n"); + printf(" @ set PC to \n"); +} + + +static void help08(void) { + printf(" p show PSW\n"); + printf(" p set PSW to \n"); +} + + +static void help09(void) { + printf(" r show all registers\n"); + printf(" r show register \n"); + printf(" r set register to \n"); +} + + +static void help10(void) { + printf(" d dump 256 bytes starting at PC\n"); + printf(" d dump 256 bytes starting at \n"); + printf(" d dump bytes starting at \n"); +} + + +static void help11(void) { + printf(" mw show memory word at PC\n"); + printf(" mw show memory word at \n"); + printf(" mw set memory word at to \n"); +} + + +static void help12(void) { + printf(" mh show memory halfword at PC\n"); + printf(" mh show memory halfword at \n"); + printf(" mh set memory halfword at to \n"); +} + + +static void help13(void) { + printf(" mb show memory byte at PC\n"); + printf(" mb show memory byte at \n"); + printf(" mb set memory byte at to \n"); +} + + +static void help14(void) { + printf(" t show TLB contents\n"); + printf(" t show TLB contents at \n"); + printf(" t p set TLB contents at to page \n"); + printf(" t f set TLB contents at to frame \n"); +} + + +static void help15(void) { + printf(" boot load and execute first sector of disk \n"); +} + + +static Bool getHexNumber(char *str, Word *valptr) { + char *end; + + *valptr = strtoul(str, &end, 16); + return *end == '\0'; +} + + +static Bool getDecNumber(char *str, int *valptr) { + char *end; + + *valptr = strtoul(str, &end, 10); + return *end == '\0'; +} + + +static void showPC(void) { + Word pc, psw; + Word instr; + + pc = cpuGetPC(); + psw = cpuGetPSW(); + instr = mmuReadWord(pc); + printf("PC %08X [PC] %08X %s\n", + pc, instr, disasm(instr, pc)); +} + + +static void showBreak(void) { + Word brk; + + brk = cpuGetBreak(); + printf("Brk "); + if (cpuTestBreak()) { + printf("%08X", brk); + } else { + printf("--------"); + } + printf("\n"); +} + + +static void showPSW(void) { + Word psw; + int i; + + psw = cpuGetPSW(); + printf(" xxxx V UPO IPO IACK MASK\n"); + printf("PSW "); + for (i = 31; i >= 0; i--) { + if (i == 27 || i == 26 || i == 23 || i == 20 || i == 15) { + printf(" "); + } + printf("%c", psw & (1 << i) ? '1' : '0'); + } + printf("\n"); +} + + +static void doHelp(char *tokens[], int n) { + int i; + + if (n == 1) { + help(); + } else if (n == 2) { + for (i = 0; i < numCommands; i++) { + if (strcmp(commands[i].name, tokens[1]) == 0) { + (*commands[i].hlpProc)(); + return; + } + } + printf("no help available for '%s', sorry\n", tokens[1]); + } else { + help00(); + } +} + + +static void doArith(char *tokens[], int n) { + Word num1, num2, num3, num4; + + if (n == 3) { + if (!getHexNumber(tokens[1], &num1)) { + printf("illegal first number\n"); + return; + } + if (!getHexNumber(tokens[2], &num2)) { + printf("illegal second number\n"); + return; + } + num3 = num1 + num2; + num4 = num1 - num2; + printf("add = %08X, sub = %08X\n", num3, num4); + } else { + help01(); + } +} + + +static void doAssemble(char *tokens[], int n) { + Word addr; + Word psw; + char prompt[30]; + char *line; + char *msg; + Word instr; + + if (n == 1) { + addr = cpuGetPC(); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + } else { + help02(); + return; + } + addr &= ~0x00000003; + psw = cpuGetPSW(); + while (1) { + sprintf(prompt, "ASM @ %08X: ", addr); + line = getLine(prompt); + if (*line == '\0' || *line == '\n') { + break; + } + addHist(line); + msg = asmInstr(line, addr, &instr); + if (msg != NULL) { + printf("%s\n", msg); + } else { + mmuWriteWord(addr, instr); + addr += 4; + } + } +} + + +static void doUnassemble(char *tokens[], int n) { + Word addr, count; + Word psw; + int i; + Word instr; + + if (n == 1) { + addr = cpuGetPC(); + count = 16; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + count = 16; + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &count)) { + printf("illegal count\n"); + return; + } + if (count == 0) { + return; + } + } else { + help03(); + return; + } + addr &= ~0x00000003; + psw = cpuGetPSW(); + for (i = 0; i < count; i++) { + instr = mmuReadWord(addr); + printf("%08X: %08X %s\n", + addr, instr, disasm(instr, addr)); + if (addr + 4 < addr) { + /* wrap-around */ + break; + } + addr += 4; + } +} + + +static void doBreak(char *tokens[], int n) { + Word addr; + + if (n == 1) { + cpuResetBreak(); + showBreak(); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + addr &= ~0x00000003; + cpuSetBreak(addr); + showBreak(); + } else { + help04(); + } +} + + +static void doContinue(char *tokens[], int n) { + Word count, i; + Word addr; + + if (n == 1) { + count = 1; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &count) || count == 0) { + printf("illegal count\n"); + return; + } + } else { + help05(); + return; + } + for (i = 0; i < count; i++) { + cpuRun(); + } + addr = cpuGetPC(); + printf("Break at %08X\n", addr); + showPC(); +} + + +static void doStep(char *tokens[], int n) { + Word count, i; + + if (n == 1) { + count = 1; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &count) || count == 0) { + printf("illegal count\n"); + return; + } + } else { + help06(); + return; + } + for (i = 0; i < count; i++) { + cpuStep(); + } + showPC(); +} + + +static void doPC(char *tokens[], int n) { + Word addr; + + if (n == 1) { + showPC(); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + addr &= ~0x00000003; + cpuSetPC(addr); + showPC(); + } else { + help07(); + } +} + + +static void explainPSW(Word data) { + int i; + + printf("interrupt vector : %s (%s)\n", + data & PSW_V ? "on " : "off", + data & PSW_V ? "RAM" : "ROM"); + printf("current user mode : %s (%s)\n", + data & PSW_UM ? "on " : "off", + data & PSW_UM ? "user" : "kernel"); + printf("previous user mode : %s (%s)\n", + data & PSW_PUM ? "on " : "off", + data & PSW_PUM ? "user" : "kernel"); + printf("old user mode : %s (%s)\n", + data & PSW_OUM ? "on " : "off", + data & PSW_OUM ? "user" : "kernel"); + printf("current interrupt enable : %s (%s)\n", + data & PSW_IE ? "on " : "off", + data & PSW_IE ? "enabled" : "disabled"); + printf("previous interrupt enable : %s (%s)\n", + data & PSW_PIE ? "on " : "off", + data & PSW_PIE ? "enabled" : "disabled"); + printf("old interrupt enable : %s (%s)\n", + data & PSW_OIE ? "on " : "off", + data & PSW_OIE ? "enabled" : "disabled"); + printf("last interrupt acknowledged : %02X (%s)\n", + (data & PSW_PRIO_MASK) >> 16, + exceptionToString((data & PSW_PRIO_MASK) >> 16)); + for (i = 15; i >= 0; i--) { + printf("%-35s: %s (%s)\n", + exceptionToString(i), + data & (1 << i) ? "on " : "off", + data & (1 << i) ? "enabled" : "disabled"); + } +} + + +static void doPSW(char *tokens[], int n) { + Word data; + + if (n == 1) { + data = cpuGetPSW(); + showPSW(); + explainPSW(data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &data)) { + printf("illegal data\n"); + return; + } + data &= 0x0FFFFFFF; + cpuSetPSW(data); + showPSW(); + explainPSW(data); + } else { + help08(); + } +} + + +static void doRegister(char *tokens[], int n) { + int i, j; + int reg; + Word data; + + if (n == 1) { + for (i = 0; i < 8; i++) { + for (j = 0; j < 4; j++) { + reg = 8 * j + i; + data = cpuGetReg(reg); + printf("$%-2d %08X ", reg, data); + } + printf("\n"); + } + showPSW(); + showBreak(); + showPC(); + } else if (n == 2) { + if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) { + printf("illegal register number\n"); + return; + } + data = cpuGetReg(reg); + printf("$%-2d %08X\n", reg, data); + } else if (n == 3) { + if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) { + printf("illegal register number\n"); + return; + } + if (!getHexNumber(tokens[2], &data)) { + printf("illegal data\n"); + return; + } + cpuSetReg(reg, data); + } else { + help09(); + } +} + + +static void doDump(char *tokens[], int n) { + Word addr, count; + Word psw; + Word lo, hi, curr; + int lines, i, j; + Word tmp; + Byte c; + + if (n == 1) { + addr = cpuGetPC(); + count = 16 * 16; + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + count = 16 * 16; + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &count)) { + printf("illegal count\n"); + return; + } + if (count == 0) { + return; + } + } else { + help10(); + return; + } + psw = cpuGetPSW(); + lo = addr & ~0x0000000F; + hi = addr + count - 1; + if (hi < lo) { + /* wrap-around */ + hi = 0xFFFFFFFF; + } + lines = (hi - lo + 16) >> 4; + curr = lo; + for (i = 0; i < lines; i++) { + printf("%08X: ", curr); + for (j = 0; j < 16; j++) { + tmp = curr + j; + if (tmp < addr || tmp > hi) { + printf(" "); + } else { + c = mmuReadByte(tmp); + printf("%02X", c); + } + printf(" "); + } + printf(" "); + for (j = 0; j < 16; j++) { + tmp = curr + j; + if (tmp < addr || tmp > hi) { + printf(" "); + } else { + c = mmuReadByte(tmp); + if (c >= 32 && c <= 126) { + printf("%c", c); + } else { + printf("."); + } + } + } + printf("\n"); + curr += 16; + } +} + + +static void doMemoryWord(char *tokens[], int n) { + Word psw; + Word addr; + Word data; + Word tmpData; + + psw = cpuGetPSW(); + if (n == 1) { + addr = cpuGetPC(); + data = mmuReadWord(addr); + printf("%08X: %08X\n", addr, data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + data = mmuReadWord(addr); + printf("%08X: %08X\n", addr, data); + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &tmpData)) { + printf("illegal data\n"); + return; + } + data = tmpData; + mmuWriteWord(addr, data); + } else { + help11(); + } +} + + +static void doMemoryHalf(char *tokens[], int n) { + Word psw; + Word addr; + Half data; + Word tmpData; + + psw = cpuGetPSW(); + if (n == 1) { + addr = cpuGetPC(); + data = mmuReadHalf(addr); + printf("%08X: %04X\n", addr, data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + data = mmuReadHalf(addr); + printf("%08X: %04X\n", addr, data); + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &tmpData)) { + printf("illegal data\n"); + return; + } + data = (Half) tmpData; + mmuWriteHalf(addr, data); + } else { + help12(); + } +} + + +static void doMemoryByte(char *tokens[], int n) { + Word psw; + Word addr; + Byte data; + Word tmpData; + + psw = cpuGetPSW(); + if (n == 1) { + addr = cpuGetPC(); + data = mmuReadByte(addr); + printf("%08X: %02X\n", addr, data); + } else if (n == 2) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + data = mmuReadByte(addr); + printf("%08X: %02X\n", addr, data); + } else if (n == 3) { + if (!getHexNumber(tokens[1], &addr)) { + printf("illegal address\n"); + return; + } + if (!getHexNumber(tokens[2], &tmpData)) { + printf("illegal data\n"); + return; + } + data = (Byte) tmpData; + mmuWriteByte(addr, data); + } else { + help13(); + } +} + + +static void doTLB(char *tokens[], int n) { + int index; + TLB_Entry tlbEntry; + Word data; + + if (n == 1) { + for (index = 0; index < TLB_SIZE; index++) { + tlbEntry = mmuGetTLB(index); + printf("TLB[%02d] page %08X frame %08X %c %c\n", + index, tlbEntry.page, tlbEntry.frame, + tlbEntry.write ? 'w' : '-', + tlbEntry.valid ? 'v' : '-'); + } + printf("Index(1) %08X\n", mmuGetIndex()); + printf("EntryHi(2) %08X\n", mmuGetEntryHi()); + printf("EntryLo(3) %08X\n", mmuGetEntryLo()); + } else if (n == 2) { + if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) { + printf("illegal TLB index\n"); + return; + } + tlbEntry = mmuGetTLB(index); + printf("TLB[%02d] page %08X frame %08X %c %c\n", + index, tlbEntry.page, tlbEntry.frame, + tlbEntry.write ? 'w' : '-', + tlbEntry.valid ? 'v' : '-'); + } else if (n == 3) { + help14(); + } else if (n == 4) { + if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) { + printf("illegal TLB index\n"); + return; + } + if (!getHexNumber(tokens[3], &data)) { + printf("illegal data\n"); + return; + } + tlbEntry = mmuGetTLB(index); + if (strcmp(tokens[2], "p") == 0) { + tlbEntry.page = data & PAGE_MASK; + } else + if (strcmp(tokens[2], "f") == 0) { + tlbEntry.frame = data & PAGE_MASK; + tlbEntry.write = data & TLB_WRITE ? true : false; + tlbEntry.valid = data & TLB_VALID ? true : false; + } else { + printf("TLB selector is not one of 'p' or 'f'\n"); + return; + } + mmuSetTLB(index, tlbEntry); + printf("TLB[%02d] page %08X frame %08X %c %c\n", + index, tlbEntry.page, tlbEntry.frame, + tlbEntry.write ? 'w' : '-', + tlbEntry.valid ? 'v' : '-'); + } else { + help14(); + } +} + + +static void doBoot(char *tokens[], int n) { + int dskno; + + if (n == 2) { + if (!getDecNumber(tokens[1], &dskno) || dskno < 0 || dskno > 1) { + printf("illegal disk number\n"); + return; + } + boot(dskno); + } else { + help15(); + } +} + + +Command commands[] = { + { "help", help00, doHelp }, + { "+", help01, doArith }, + { "a", help02, doAssemble }, + { "u", help03, doUnassemble }, + { "b", help04, doBreak }, + { "c", help05, doContinue }, + { "s", help06, doStep }, + { "@", help07, doPC }, + { "p", help08, doPSW }, + { "r", help09, doRegister }, + { "d", help10, doDump }, + { "mw", help11, doMemoryWord }, + { "mh", help12, doMemoryHalf }, + { "mb", help13, doMemoryByte }, + { "t", help14, doTLB }, + { "boot", help15, doBoot }, +}; + +int numCommands = sizeof(commands) / sizeof(commands[0]); + + +static void doCommand(char *line) { + char *tokens[MAX_TOKENS]; + int n; + char *p; + int i; + + n = 0; + p = strtok(line, " \t\n"); + while (p != NULL) { + if (n == MAX_TOKENS) { + printf("too many tokens on line\n"); + return; + } + tokens[n++] = p; + p = strtok(NULL, " \t\n"); + } + if (n == 0) { + return; + } + for (i = 0; i < numCommands; i++) { + if (strcmp(commands[i].name, tokens[0]) == 0) { + (*commands[i].cmdProc)(tokens, n); + return; + } + } + help(); +} + + +static char *article(char firstLetterOfNoun) { + switch (firstLetterOfNoun) { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + return "An"; + default: + return "A"; + } +} + + +static void interactiveException(int exception) { + char *what; + + what = exceptionToString(exception); + printf("\n"); + printf("NOTE: %s %s occurred while executing the command.\n", + article(*what), what); + printf(" This event will not alter the state of the CPU.\n"); +} + + +void execCommand(char *line) { + MonitorState commandState; + + if (saveState(&commandState)) { + /* initialization */ + monitorReturn = &commandState; + doCommand(line); + } else { + /* an exception was thrown */ + interactiveException((userContext.psw & PSW_PRIO_MASK) >> 16); + } + monitorReturn = NULL; +} Index: monitor/monitor/asm.c =================================================================== --- monitor/monitor/asm.c (nonexistent) +++ monitor/monitor/asm.c (revision 16) @@ -0,0 +1,370 @@ +/* + * asm.c -- assembler + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "instr.h" +#include "asm.h" + + +#define MAX_TOKENS 10 + + +static char *msgs[] = { + /* 0 */ "too many tokens on line", + /* 1 */ "empty line", + /* 2 */ "unknown instruction name", + /* 3 */ "unknown instruction format", + /* 4 */ "excess tokens on line", + /* 5 */ "too few operands", + /* 6 */ "illegal register", + /* 7 */ "illegal immediate value", + /* 8 */ "immediate value out of range", + /* 9 */ "target is not aligned", + /* 10 */ "target cannot be reached" +}; + + +static Bool asmReg(char *token, int *reg) { + char *end; + + if (*token != '$') { + return false; + } + *reg = strtoul(token + 1, &end, 10); + if (*end != '\0') { + return false; + } + if (*reg < 0 || *reg >= 32) { + return false; + } + return true; +} + + +static Bool asmNum(char *token, unsigned int *val) { + char *end; + + *val = strtoul(token, &end, 16); + return *end == '\0'; +} + + +char *asmInstr(char *line, Word addr, Word *instrPtr) { + char *tokens[MAX_TOKENS]; + int n; + char *p; + Instr *instr; + Word result; + int r1, r2, r3; + unsigned int uimm; + signed int simm; + + /* separate tokens */ + n = 0; + p = strtok(line, " \t\n,"); + while (p != NULL) { + if (n == MAX_TOKENS) { + return msgs[0]; + } + tokens[n++] = p; + p = strtok(NULL, " \t\n,"); + } + if (n == 0) { + return msgs[1]; + } + /* lookup mnemonic */ + instr = lookupInstr(tokens[0]); + if (instr == NULL) { + return msgs[2]; + } + /* do processing according to format */ + switch (instr->format) { + case FORMAT_N: + /* no operands (but may get a constant operand) */ + if (n > 2) { + return msgs[4]; + } + if (n < 1) { + return msgs[5]; + } + if (n == 2) { + if (!asmNum(tokens[1], &uimm)) { + return msgs[7]; + } + } else { + uimm = 0; + } + result = ((Word) instr->opcode << 26) | + (uimm & MASK(26)); + break; + case FORMAT_RH: + /* one register and a half operand */ + if (n > 3) { + return msgs[4]; + } + if (n < 3) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmNum(tokens[2], &uimm)) { + return msgs[7]; + } + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 16) | + (uimm & MASK(16)); + break; + case FORMAT_RHH: + /* one register and a half operand */ + /* ATTENTION: high-order 16 bits encoded */ + if (n > 3) { + return msgs[4]; + } + if (n < 3) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmNum(tokens[2], &uimm)) { + return msgs[7]; + } + uimm >>= 16; + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 16) | + (uimm & MASK(16)); + break; + case FORMAT_RRH: + /* two registers and a half operand */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmNum(tokens[3], &uimm)) { + return msgs[7]; + } + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r1 << 16) | + (uimm & MASK(16)); + break; + case FORMAT_RRS: + /* two registers and a signed half operand */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmNum(tokens[3], (unsigned int *) &simm)) { + return msgs[7]; + } + if (simm >= (signed) (1 << 15) || + simm < - (signed) (1 << 15)) { + return msgs[8]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r1 << 16) | + (simm & MASK(16)); + break; + case FORMAT_RRR: + /* three register operands */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmReg(tokens[3], &r3)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r3 << 16) | + (r1 << 11); + break; + case FORMAT_RRX: + /* either FORMAT_RRR or FORMAT_RRH */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (*tokens[3] == '$') { + /* FORMAT_RRR */ + if (!asmReg(tokens[3], &r3)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r3 << 16) | + (r1 << 11); + } else { + /* FORMAT_RRH */ + if (!asmNum(tokens[3], &uimm)) { + return msgs[7]; + } + if (uimm >= (unsigned) (1 << 16)) { + return msgs[8]; + } + result = (((Word) instr->opcode + 1) << 26) | + (r2 << 21) | + (r1 << 16) | + (uimm & MASK(16)); + } + break; + case FORMAT_RRY: + /* either FORMAT_RRR or FORMAT_RRS */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (*tokens[3] == '$') { + /* FORMAT_RRR */ + if (!asmReg(tokens[3], &r3)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r2 << 21) | + (r3 << 16) | + (r1 << 11); + } else { + /* FORMAT_RRS */ + if (!asmNum(tokens[3], (unsigned int *) &simm)) { + return msgs[7]; + } + if (simm >= (signed) (1 << 15) || + simm < - (signed) (1 << 15)) { + return msgs[8]; + } + result = (((Word) instr->opcode + 1) << 26) | + (r2 << 21) | + (r1 << 16) | + (simm & MASK(16)); + } + break; + case FORMAT_RRB: + /* two registers and a 16 bit signed offset operand */ + if (n > 4) { + return msgs[4]; + } + if (n < 4) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + if (!asmReg(tokens[2], &r2)) { + return msgs[6]; + } + if (!asmNum(tokens[3], (unsigned int *) &simm)) { + return msgs[7]; + } + if ((simm & 0x00000003) != 0) { + return msgs[9]; + } + simm -= addr + 4; + simm /= 4; + if (simm >= (signed) (1 << 15) || + simm < - (signed) (1 << 15)) { + return msgs[10]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 21) | + (r2 << 16) | + (simm & MASK(16)); + break; + case FORMAT_J: + /* no registers and a 26 bit signed offset operand */ + if (n > 2) { + return msgs[4]; + } + if (n < 2) { + return msgs[5]; + } + if (!asmNum(tokens[1], (unsigned int *) &simm)) { + return msgs[7]; + } + if ((simm & 0x00000003) != 0) { + return msgs[9]; + } + simm -= addr + 4; + simm /= 4; + if (simm >= (signed) (1 << 25) || + simm < - (signed) (1 << 25)) { + return msgs[10]; + } + result = ((Word) instr->opcode << 26) | + (simm & MASK(26)); + break; + case FORMAT_JR: + /* one register operand */ + if (n > 2) { + return msgs[4]; + } + if (n < 2) { + return msgs[5]; + } + if (!asmReg(tokens[1], &r1)) { + return msgs[6]; + } + result = ((Word) instr->opcode << 26) | + (r1 << 21); + break; + default: + return msgs[3]; + } + /* line successfully assembled */ + *instrPtr = result; + return NULL; +} Index: monitor/monitor/keyboard.s =================================================================== --- monitor/monitor/keyboard.s (nonexistent) +++ monitor/monitor/keyboard.s (revision 16) @@ -0,0 +1,140 @@ +; +; keyboard.s -- a PC keyboard as input device +; + +;*************************************************************** + + .set kbdbase,0xF0200000 ; keyboard base address + +; .import cout +; .import byteout + + .import xltbl1 ; kbd translation table 1 + .import xltbl2 ; kbd translation table 2 + + .export kbdinit ; initialize keyboard + .export kbdinchk ; check if input available + .export kbdin ; do keyboard input + +;*************************************************************** + + .code + .align 4 + +kbdinit: + jr $31 + +kbdinchk: + add $8,$0,kbdbase + ldw $2,$8,0 + and $2,$2,1 + jr $31 + +kbdin: + sub $29,$29,12 + stw $31,$29,8 + stw $16,$29,4 + stw $17,$29,0 +kbdin0: + jal kbdinp + add $16,$2,$0 ; key1 in $16 + add $8,$0,0xF0 + bne $16,$8,kbdin2 +kbdin1: + jal kbdinp + j kbdin0 +kbdin2: + jal kbdinp + add $17,$2,$0 ; key2 in $17 + beq $17,$16,kbdin2 + add $8,$0,0xF0 + beq $17,$8,kbdin3 + j kbdin5 +kbdin3: + jal kbdinp + bne $2,$16,kbdin2 +kbdin4: + add $4,$16,$0 + add $5,$0,xltbl1 + jal xlat + j kbdx +kbdin5: + jal kbdinp + add $8,$0,0xF0 + bne $2,$8,kbdin5 +kbdin6: + jal kbdinp + beq $2,$16,kbdin7 + beq $2,$17,kbdin9 + j kbdin5 +kbdin7: + jal kbdinp + add $8,$0,0xF0 + bne $2,$8,kbdin7 +kbdin8: + jal kbdinp + bne $2,$17,kbdin7 + j kbdin11 +kbdin9: + jal kbdinp + add $8,$0,0xF0 + bne $2,$8,kbdin9 +kbdin10: + jal kbdinp + bne $2,$16,kbdin9 + j kbdin11 +kbdin11: + add $8,$0,0x12 ; left shift key + beq $16,$8,kbdin12 + add $8,$0,0x59 ; right shift key + bne $16,$8,kbdin13 +kbdin12: + add $4,$17,$0 + add $5,$0,xltbl2 + jal xlat + j kbdx +kbdin13: + add $4,$16,$0 + add $5,$0,xltbl1 + jal xlat + j kbdx +kbdx: + ldw $17,$29,0 + ldw $16,$29,4 + ldw $31,$29,8 + add $29,$29,12 + jr $31 + +kbdinp: + add $8,$0,kbdbase +kbdinp1: + ldw $9,$8,0 + and $9,$9,1 + beq $9,$0,kbdinp1 + ldw $2,$8,4 + add $9,$0,0xE0 + beq $2,$9,kbdinp1 + add $9,$0,0xE1 + beq $2,$9,kbdinp1 + jr $31 + +xlat: + sub $29,$29,8 + stw $31,$29,4 + stw $16,$29,0 + and $16,$4,0xFF + add $8,$16,$5 + ldbu $2,$8,0 + bne $2,$0,xlat1 +; add $4,$0,'<' +; jal cout +; add $4,$16,$0 +; jal byteout +; add $4,$0,'>' +; jal cout + add $2,$16,$0 +xlat1: + ldw $16,$29,0 + ldw $31,$29,4 + add $29,$29,8 + jr $31 Index: monitor/monitor/disasm.c =================================================================== --- monitor/monitor/disasm.c (nonexistent) +++ monitor/monitor/disasm.c (revision 16) @@ -0,0 +1,138 @@ +/* + * disasm.c -- disassembler + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "instr.h" +#include "disasm.h" + + +static char instrBuffer[100]; + + +static void disasmN(char *opName, Word immed) { + if (immed == 0) { + sprintf(instrBuffer, "%-7s", opName); + } else { + sprintf(instrBuffer, "%-7s %08X", opName, immed); + } +} + + +static void disasmRH(char *opName, int r1, Half immed) { + sprintf(instrBuffer, "%-7s $%d,%04X", opName, r1, immed); +} + + +static void disasmRHH(char *opName, int r1, Half immed) { + sprintf(instrBuffer, "%-7s $%d,%08X", opName, r1, (Word) immed << 16); +} + + +static void disasmRRH(char *opName, int r1, int r2, Half immed) { + sprintf(instrBuffer, "%-7s $%d,$%d,%04X", opName, r1, r2, immed); +} + + +static void disasmRRS(char *opName, int r1, int r2, Half immed) { + sprintf(instrBuffer, "%-7s $%d,$%d,%s%04X", opName, r1, r2, + SIGN(16) & immed ? "-" : "+", + SIGN(16) & immed ? -(signed)SEXT16(immed) : SEXT16(immed)); +} + + +static void disasmRRR(char *opName, int r1, int r2, int r3) { + sprintf(instrBuffer, "%-7s $%d,$%d,$%d", opName, r1, r2, r3); +} + + +static void disasmRRB(char *opName, int r1, int r2, Half offset, Word locus) { + sprintf(instrBuffer, "%-7s $%d,$%d,%08X", opName, + r1, r2, (locus + 4) + (SEXT16(offset) << 2)); +} + + +static void disasmJ(char *opName, Word offset, Word locus) { + sprintf(instrBuffer, "%-7s %08X", opName, + (locus + 4) + (SEXT26(offset) << 2)); +} + + +static void disasmJR(char *opName, int r1) { + sprintf(instrBuffer, "%-7s $%d", opName, r1); +} + + +char *disasm(Word instr, Word locus) { + Byte opcode; + Instr *ip; + + opcode = (instr >> 26) & 0x3F; + ip = instrCodeTbl[opcode]; + if (ip == NULL) { + disasmN("???", 0); + } else { + switch (ip->format) { + case FORMAT_N: + disasmN(ip->name, instr & 0x03FFFFFF); + break; + case FORMAT_RH: + disasmRH(ip->name, (instr >> 16) & 0x1F, instr & 0x0000FFFF); + break; + case FORMAT_RHH: + disasmRHH(ip->name, (instr >> 16) & 0x1F, instr & 0x0000FFFF); + break; + case FORMAT_RRH: + disasmRRH(ip->name, (instr >> 16) & 0x1F, + (instr >> 21) & 0x1F, instr & 0x0000FFFF); + break; + case FORMAT_RRS: + disasmRRS(ip->name, (instr >> 16) & 0x1F, + (instr >> 21) & 0x1F, instr & 0x0000FFFF); + break; + case FORMAT_RRR: + disasmRRR(ip->name, (instr >> 11) & 0x1F, + (instr >> 21) & 0x1F, (instr >> 16) & 0x1F); + break; + case FORMAT_RRX: + if ((opcode & 1) == 0) { + /* the FORMAT_RRR variant */ + disasmRRR(ip->name, (instr >> 11) & 0x1F, + (instr >> 21) & 0x1F, (instr >> 16) & 0x1F); + } else { + /* the FORMAT_RRH variant */ + disasmRRH(ip->name, (instr >> 16) & 0x1F, + (instr >> 21) & 0x1F, instr & 0x0000FFFF); + } + break; + case FORMAT_RRY: + if ((opcode & 1) == 0) { + /* the FORMAT_RRR variant */ + disasmRRR(ip->name, (instr >> 11) & 0x1F, + (instr >> 21) & 0x1F, (instr >> 16) & 0x1F); + } else { + /* the FORMAT_RRS variant */ + disasmRRS(ip->name, (instr >> 16) & 0x1F, + (instr >> 21) & 0x1F, instr & 0x0000FFFF); + } + break; + case FORMAT_RRB: + disasmRRB(ip->name, (instr >> 21) & 0x1F, + (instr >> 16) & 0x1F, instr & 0x0000FFFF, locus); + break; + case FORMAT_J: + disasmJ(ip->name, instr & 0x03FFFFFF, locus); + break; + case FORMAT_JR: + disasmJR(ip->name, (instr >> 21) & 0x1F); + break; + default: + printf("illegal entry in instruction table\n"); + break; + } + } + return instrBuffer; +} Index: monitor/monitor/sctio-ctl.s =================================================================== --- monitor/monitor/sctio-ctl.s (nonexistent) +++ monitor/monitor/sctio-ctl.s (revision 16) @@ -0,0 +1,133 @@ +; +; sctio-ctl.s -- disk sector I/O for disk made available by disk controller +; + +;*************************************************************** + + .set dskbase,0xF0400000 ; disk base address + .set dskctrl,0 ; control register + .set dskcnt,4 ; count register + .set dsksct,8 ; sector register + .set dskcap,12 ; capacity register + .set dskbuf,0x00080000 ; disk buffer + + .set ctrlstrt,0x01 ; start bit + .set ctrlien,0x02 ; interrupt enable bit + .set ctrlwrt,0x04 ; write bit + .set ctrlerr,0x08 ; error bit + .set ctrldone,0x10 ; done bit + .set ctrlrdy,0x20 ; ready bit + + .set sctsize,512 ; sector size in bytes + + .set retries,1000000 ; retries to get disk ready + + .export sctcapctl ; determine disk capacity + .export sctioctl ; do disk I/O + +;*************************************************************** + + .code + .align 4 + +sctcapctl: + add $8,$0,retries ; set retry count + add $9,$0,dskbase +sctcap1: + ldw $10,$9,dskctrl + and $10,$10,ctrlrdy ; ready? + bne $10,$0,sctcapok ; yes - jump + sub $8,$8,1 + bne $8,$0,sctcap1 ; try again + add $2,$0,0 ; no disk found + j sctcapx +sctcapok: + ldw $2,$9,dskcap ; get disk capacity +sctcapx: + jr $31 + +sctioctl: + sub $29,$29,24 + stw $31,$29,20 + stw $16,$29,16 + stw $17,$29,12 + stw $18,$29,8 + stw $19,$29,4 + stw $20,$29,0 + add $16,$4,$0 ; command + add $17,$5,$0 ; sector number + add $18,$6,0xC0000000 ; memory address, virtualized + add $19,$7,$0 ; number of sectors + + add $8,$0,'r' + beq $16,$8,sctrd + add $8,$0,'w' + beq $16,$8,sctwr + add $2,$0,0xFF ; illegal command + j sctx + +sctrd: + add $2,$0,$0 ; return ok + beq $19,$0,sctx ; if no (more) sectors + add $8,$0,dskbase + add $9,$0,1 + stw $9,$8,dskcnt ; number of sectors + stw $17,$8,dsksct ; sector number on disk + add $9,$0,ctrlstrt + stw $9,$8,dskctrl ; start command +sctrd1: + ldw $2,$8,dskctrl + and $9,$2,ctrldone ; done? + beq $9,$0,sctrd1 ; no - wait + and $9,$2,ctrlerr ; error? + bne $9,$0,sctx ; yes - leave + add $8,$0,dskbase + dskbuf ; transfer data + add $9,$0,sctsize +sctrd2: + ldw $10,$8,0 ; from disk buffer + stw $10,$18,0 ; to memory + add $8,$8,4 + add $18,$18,4 + sub $9,$9,4 + bne $9,$0,sctrd2 + add $17,$17,1 ; increment sector number + sub $19,$19,1 ; decrement number of sectors + j sctrd ; next sector + +sctwr: + add $2,$0,$0 ; return ok + beq $19,$0,sctx ; if no (more) sectors + add $8,$0,dskbase + dskbuf ; transfer data + add $9,$0,sctsize +sctwr1: + ldw $10,$18,0 ; from memory + stw $10,$8,0 ; to disk buffer + add $18,$18,4 + add $8,$8,4 + sub $9,$9,4 + bne $9,$0,sctwr1 + add $8,$0,dskbase + add $9,$0,1 + stw $9,$8,dskcnt ; number of sectors + stw $17,$8,dsksct ; sector number on disk + add $9,$0,ctrlwrt | ctrlstrt + stw $9,$8,dskctrl ; start command +sctwr2: + ldw $2,$8,dskctrl + and $9,$2,ctrldone ; done? + beq $9,$0,sctwr2 ; no - wait + and $9,$2,ctrlerr ; error? + bne $9,$0,sctx ; yes - leave + add $17,$17,1 ; increment sector number + sub $19,$19,1 ; decrement number of sectors + j sctwr ; next sector + +sctx: + ldw $20,$29,0 + ldw $19,$29,4 + ldw $18,$29,8 + ldw $17,$29,12 + ldw $16,$29,16 + ldw $31,$29,20 + add $29,$29,24 + jr $31 Index: monitor/monitor/command.h =================================================================== --- monitor/monitor/command.h (nonexistent) +++ monitor/monitor/command.h (revision 16) @@ -0,0 +1,13 @@ +/* + * command.h -- command interpreter + */ + + +#ifndef _COMMAND_H_ +#define _COMMAND_H_ + + +void execCommand(char *line); + + +#endif /* _COMMAND_H_ */ Index: monitor/monitor/main.c =================================================================== --- monitor/monitor/main.c (nonexistent) +++ monitor/monitor/main.c (revision 16) @@ -0,0 +1,27 @@ +/* + * main.c -- the main program + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "command.h" +#include "getline.h" +#include "instr.h" +#include "cpu.h" + + +int main(void) { + char *line; + + printf("\n\nECO32 Machine Monitor 1.0\n\n"); + initInstrTable(); + cpuSetPC(0xC0000000); + while (1) { + line = getLine("ECO32 > "); + addHist(line); + execCommand(line); + } + return 0; +} Index: monitor/monitor/romlib.c =================================================================== --- monitor/monitor/romlib.c (nonexistent) +++ monitor/monitor/romlib.c (revision 16) @@ -0,0 +1,636 @@ +/* + * romlib.c -- the ROM library + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "start.h" + + +/**************************************************************/ + + +/* + * This is only for debugging. + * Place a breakpoint at the very beginning of this routine + * and call it wherever you want to break execution. + */ +void debugBreak(void) { +} + + +/**************************************************************/ + + +/* + * Count the length of a string (without terminating null character). + */ +int strlen(const char *s) { + const char *p; + + p = s; + while (*p != '\0') { + p++; + } + return p - s; +} + + +/* + * Compare two strings. + * Return a number < 0, = 0, or > 0 iff the first string is less + * than, equal to, or greater than the second one, respectively. + */ +int strcmp(const char *s, const char *t) { + while (*s == *t) { + if (*s == '\0') { + return 0; + } + s++; + t++; + } + return *s - *t; +} + + +/* + * Copy string t to string s (includes terminating null character). + */ +char *strcpy(char *s, const char *t) { + char *p; + + p = s; + while ((*p = *t) != '\0') { + p++; + t++; + } + return s; +} + + +/* + * Append string t to string s. + */ +char *strcat(char *s, const char *t) { + char *p; + + p = s; + while (*p != '\0') { + p++; + } + while ((*p = *t) != '\0') { + p++; + t++; + } + return s; +} + + +/* + * Locate character c in string s. + */ +char *strchr(const char *s, char c) { + while (*s != c) { + if (*s == '\0') { + return NULL; + } + s++; + } + return (char *) s; +} + + +/* + * Extract the next token from the string s, delimited + * by any character from the delimiter string t. + */ +char *strtok(char *s, const char *t) { + static char *p; + char *q; + + if (s != NULL) { + p = s; + } else { + p++; + } + while (*p != '\0' && strchr(t, *p) != NULL) { + p++; + } + if (*p == '\0') { + return NULL; + } + q = p++; + while (*p != '\0' && strchr(t, *p) == NULL) { + p++; + } + if (*p != '\0') { + *p = '\0'; + } else { + p--; + } + return q; +} + + +/**************************************************************/ + + +/* + * Determine if a character is 'white space'. + */ +static Bool isspace(char c) { + Bool res; + + switch (c) { + case ' ': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + res = true; + break; + default: + res = false; + break; + } + return res; +} + + +/* + * Check for valid digit, and convert to value. + */ +static Bool checkDigit(char c, int base, int *value) { + if (c >= '0' && c <= '9') { + *value = c - '0'; + } else + if (c >= 'A' && c <= 'Z') { + *value = c - 'A' + 10; + } else + if (c >= 'a' && c <= 'z') { + *value = c - 'a' + 10; + } else { + return false; + } + return *value < base; +} + + +/* + * Convert initial part of string to unsigned long integer. + */ +unsigned long strtoul(const char *s, char **endp, int base) { + unsigned long res; + int sign; + int digit; + + res = 0; + while (isspace(*s)) { + s++; + } + if (*s == '+') { + sign = 1; + s++; + } else + if (*s == '-') { + sign = -1; + s++; + } else { + sign = 1; + } + if (base == 0 || base == 16) { + if (*s == '0' && + (*(s + 1) == 'x' || *(s + 1) == 'X')) { + /* base is 16 */ + s += 2; + base = 16; + } else { + /* base is 0 or 16, but number does not start with "0x" */ + if (base == 0) { + if (*s == '0') { + s++; + base = 8; + } else { + base = 10; + } + } else { + /* take base as is */ + } + } + } else { + /* take base as is */ + } + while (checkDigit(*s, base, &digit)) { + res *= base; + res += digit; + s++; + } + if (endp != NULL) { + *endp = (char *) s; + } + return sign * res; +} + + +/**************************************************************/ + + +/* + * Exchange two array items of a given size. + */ +static void xchg(char *p, char *q, int size) { + char t; + + while (size--) { + t = *p; + *p++ = *q; + *q++ = t; + } +} + + +/* + * This is a recursive version of quicksort. + */ +static void sort(char *l, char *r, int size, + int (*cmp)(const void *, const void *)) { + char *i; + char *j; + char *x; + + i = l; + j = r; + x = l + (((r - l) / size) / 2) * size; + do { + while (cmp(i, x) < 0) { + i += size; + } + while (cmp(x, j) < 0) { + j -= size; + } + if (i <= j) { + /* exchange array elements i and j */ + /* attention: update x if it is one of these */ + if (x == i) { + x = j; + } else + if (x == j) { + x = i; + } + xchg(i, j, size); + i += size; + j -= size; + } + } while (i <= j); + if (l < j) { + sort(l, j, size, cmp); + } + if (i < r) { + sort(i, r, size, cmp); + } +} + + +/* + * External interface for the quicksort algorithm. + */ +void qsort(void *base, int n, int size, + int (*cmp)(const void *, const void*)) { + sort((char *) base, (char *) base + (n - 1) * size, size, cmp); +} + + +/**************************************************************/ + + +/* + * Input a character from the console. + */ +char getchar(void) { + return cin(); +} + + +/* + * Output a character on the console. + * Replace LF by CR/LF. + */ +void putchar(char c) { + if (c == '\n') { + cout('\r'); + } + cout(c); +} + + +/* + * Output a string on the console. + * Replace LF by CR/LF. + */ +void puts(const char *s) { + while (*s != '\0') { + putchar(*s); + s++; + } +} + + +/**************************************************************/ + + +/* + * Count the number of characters needed to represent + * a given number in base 10. + */ +static int countPrintn(long n) { + long a; + int res; + + res = 0; + if (n < 0) { + res++; + n = -n; + } + a = n / 10; + if (a != 0) { + res += countPrintn(a); + } + return res + 1; +} + + +/* + * Output a number in base 10. + */ +static void *printn(void *(*emit)(void *, char), void *arg, + int *nchar, long n) { + long a; + + if (n < 0) { + arg = emit(arg, '-'); + (*nchar)++; + n = -n; + } + a = n / 10; + if (a != 0) { + arg = printn(emit, arg, nchar, a); + } + arg = emit(arg, n % 10 + '0'); + (*nchar)++; + return arg; +} + + +/* + * Count the number of characters needed to represent + * a given number in a given base. + */ +static int countPrintu(unsigned long n, unsigned long b) { + unsigned long a; + int res; + + res = 0; + a = n / b; + if (a != 0) { + res += countPrintu(a, b); + } + return res + 1; +} + + +/* + * Output a number in a given base. + */ +static void *printu(void *(*emit)(void *, char), void *arg, + int *nchar, unsigned long n, unsigned long b, + Bool upperCase) { + unsigned long a; + + a = n / b; + if (a != 0) { + arg = printu(emit, arg, nchar, a, b, upperCase); + } + if (upperCase) { + arg = emit(arg, "0123456789ABCDEF"[n % b]); + (*nchar)++; + } else { + arg = emit(arg, "0123456789abcdef"[n % b]); + (*nchar)++; + } + return arg; +} + + +/* + * Output a number of filler characters. + */ +static void *fill(void *(*emit)(void *, char), void *arg, + int *nchar, int numFillers, char filler) { + while (numFillers-- > 0) { + arg = emit(arg, filler); + (*nchar)++; + } + return arg; +} + + +/* + * This function does the real work of formatted printing. + */ +static int doPrintf(void *(*emit)(void *, char), void *arg, + const char *fmt, va_list ap) { + int nchar; + char c; + int n; + long ln; + unsigned int u; + unsigned long lu; + char *s; + Bool negFlag; + char filler; + int width, count; + + nchar = 0; + while (1) { + while ((c = *fmt++) != '%') { + if (c == '\0') { + return nchar; + } + arg = emit(arg, c); + nchar++; + } + c = *fmt++; + if (c == '-') { + negFlag = true; + c = *fmt++; + } else { + negFlag = false; + } + if (c == '0') { + filler = '0'; + c = *fmt++; + } else { + filler = ' '; + } + width = 0; + while (c >= '0' && c <= '9') { + width *= 10; + width += c - '0'; + c = *fmt++; + } + if (c == 'd') { + n = va_arg(ap, int); + count = countPrintn(n); + if (width > 0 && !negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + arg = printn(emit, arg, &nchar, n); + if (width > 0 && negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + } else + if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { + u = va_arg(ap, int); + count = countPrintu(u, + c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); + if (width > 0 && !negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + arg = printu(emit, arg, &nchar, u, + c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), + c == 'X'); + if (width > 0 && negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + } else + if (c == 'l') { + c = *fmt++; + if (c == 'd') { + ln = va_arg(ap, long); + count = countPrintn(ln); + if (width > 0 && !negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + arg = printn(emit, arg, &nchar, ln); + if (width > 0 && negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + } else + if (c == 'u' || c == 'o' || c == 'x' || c == 'X') { + lu = va_arg(ap, long); + count = countPrintu(lu, + c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10)); + if (width > 0 && !negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + arg = printu(emit, arg, &nchar, lu, + c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10), + c == 'X'); + if (width > 0 && negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + } else { + arg = emit(arg, 'l'); + nchar++; + arg = emit(arg, c); + nchar++; + } + } else + if (c == 's') { + s = va_arg(ap, char *); + count = strlen(s); + if (width > 0 && !negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + while ((c = *s++) != '\0') { + arg = emit(arg, c); + nchar++; + } + if (width > 0 && negFlag) { + arg = fill(emit, arg, &nchar, width - count, filler); + } + } else + if (c == 'c') { + c = va_arg(ap, char); + arg = emit(arg, c); + nchar++; + } else { + arg = emit(arg, c); + nchar++; + } + } + /* never reached */ + return 0; +} + + +/* + * Emit a character to the console. + */ +static void *emitToConsole(void *dummy, char c) { + putchar(c); + return dummy; +} + + +/* + * Formatted output with a variable argument list. + */ +int vprintf(const char *fmt, va_list ap) { + int n; + + n = doPrintf(emitToConsole, NULL, fmt, ap); + return n; +} + + +/* + * Formatted output. + */ +int printf(const char *fmt, ...) { + int n; + va_list ap; + + va_start(ap, fmt); + n = vprintf(fmt, ap); + va_end(ap); + return n; +} + + +/* + * Emit a character to a buffer. + */ +static void *emitToBuffer(void *bufptr, char c) { + *(char *)bufptr = c; + return (char *) bufptr + 1; +} + + +/* + * Formatted output into a buffer with a variable argument list. + */ +int vsprintf(char *s, const char *fmt, va_list ap) { + int n; + + n = doPrintf(emitToBuffer, s, fmt, ap); + s[n] = '\0'; + return n; +} + + +/* + * Formatted output into a buffer. + */ +int sprintf(char *s, const char *fmt, ...) { + int n; + va_list ap; + + va_start(ap, fmt); + n = vsprintf(s, fmt, ap); + va_end(ap); + return n; +} Index: monitor/monitor/display.s =================================================================== --- monitor/monitor/display.s (nonexistent) +++ monitor/monitor/display.s (revision 16) @@ -0,0 +1,225 @@ +; +; display.s -- a memory-mapped alphanumerical display +; + +;*************************************************************** + + .set dspbase,0xF0100000 ; display base address + + .export dspinit ; initialize display + .export dspoutchk ; check for output possible + .export dspout ; do display output + +;*************************************************************** + + .code + .align 4 + + ; initialize display +dspinit: + sub $29,$29,4 + stw $31,$29,0 + jal clrscr + add $8,$0,scrrow + stw $0,$8,0 + add $8,$0,scrcol + stw $0,$8,0 + jal calcp + jal stcrs + ldw $31,$29,0 + add $29,$29,4 + jr $31 + + ; check if a character can be written +dspoutchk: + add $2,$0,1 + jr $31 + + ; output a character on the display +dspout: + sub $29,$29,8 + stw $31,$29,4 + stw $16,$29,0 + and $16,$4,0xFF + jal rmcrs + add $8,$0,' ' + bltu $16,$8,dspout2 + add $8,$0,scrptr + ldw $9,$8,0 + or $16,$16,0x07 << 8 + stw $16,$9,0 + add $9,$9,4 + stw $9,$8,0 + add $8,$0,scrcol + ldw $9,$8,0 + add $9,$9,1 + stw $9,$8,0 + add $10,$0,80 + bne $9,$10,dspout1 + jal docr + jal dolf +dspout1: + jal stcrs + ldw $16,$29,0 + ldw $31,$29,4 + add $29,$29,8 + jr $31 + +dspout2: + add $8,$0,0x0D + bne $16,$8,dspout3 + jal docr + j dspout1 + +dspout3: + add $8,$0,0x0A + bne $16,$8,dspout4 + jal dolf + j dspout1 + +dspout4: + add $8,$0,0x08 + bne $16,$8,dspout5 + jal dobs + j dspout1 + +dspout5: + j dspout1 + + ; do carriage return +docr: + sub $29,$29,4 + stw $31,$29,0 + add $8,$0,scrcol + stw $0,$8,0 + jal calcp + ldw $31,$29,0 + add $29,$29,4 + jr $31 + + ; do linefeed +dolf: + sub $29,$29,4 + stw $31,$29,0 + add $8,$0,scrrow + ldw $9,$8,0 + add $10,$0,29 + beq $9,$10,dolf1 + add $9,$9,1 + stw $9,$8,0 + jal calcp + j dolf2 +dolf1: + jal scrscr +dolf2: + ldw $31,$29,0 + add $29,$29,4 + jr $31 + + ; do backspace +dobs: + sub $29,$29,4 + stw $31,$29,0 + add $8,$0,scrcol + ldw $9,$8,0 + beq $9,$0,dobs1 + sub $9,$9,1 + stw $9,$8,0 + jal calcp +dobs1: + ldw $31,$29,0 + add $29,$29,4 + jr $31 + + ; remove cursor +rmcrs: + add $8,$0,scrptr + ldw $8,$8,0 + add $9,$0,scrchr + ldw $10,$9,0 + stw $10,$8,0 + jr $31 + + ; set cursor +stcrs: + add $8,$0,scrptr + ldw $8,$8,0 + add $9,$0,scrchr + ldw $10,$8,0 + stw $10,$9,0 + add $10,$0,(0x87 << 8) | '_' + stw $10,$8,0 + jr $31 + + ; calculate screen pointer based on row and column +calcp: + add $9,$0,dspbase + add $8,$0,scrrow + ldw $10,$8,0 + sll $10,$10,7+2 + add $9,$9,$10 + add $8,$0,scrcol + ldw $10,$8,0 + sll $10,$10,0+2 + add $9,$9,$10 + add $8,$0,scrptr + stw $9,$8,0 + jr $31 + + ; clear screen +clrscr: + add $11,$0,(0x07 << 8) | ' ' + add $8,$0,dspbase + add $9,$0,30 +clrscr1: + add $10,$0,80 +clrscr2: + stw $11,$8,0 + add $8,$8,4 + sub $10,$10,1 + bne $10,$0,clrscr2 + add $8,$8,(128-80)*4 + sub $9,$9,1 + bne $9,$0,clrscr1 + jr $31 + + ; scroll screen +scrscr: + add $8,$0,dspbase + add $9,$0,29 +scrscr1: + add $10,$0,80 +scrscr2: + ldw $11,$8,128*4 + stw $11,$8,0 + add $8,$8,4 + sub $10,$10,1 + bne $10,$0,scrscr2 + add $8,$8,(128-80)*4 + sub $9,$9,1 + bne $9,$0,scrscr1 + add $11,$0,(0x07 << 8) | ' ' + add $10,$0,80 +scrscr3: + stw $11,$8,0 + add $8,$8,4 + sub $10,$10,1 + bne $10,$0,scrscr3 + jr $31 + +;*************************************************************** + + .bss + .align 4 + +scrptr: + .word 0 + +scrrow: + .word 0 + +scrcol: + .word 0 + +scrchr: + .word 0 Index: monitor/monitor/disasm.h =================================================================== --- monitor/monitor/disasm.h (nonexistent) +++ monitor/monitor/disasm.h (revision 16) @@ -0,0 +1,13 @@ +/* + * disasm.h -- disassembler + */ + + +#ifndef _DISASM_H_ +#define _DISASM_H_ + + +char *disasm(Word instr, Word locus); + + +#endif /* _DISASM_H_ */ Index: monitor/monitor/asm.h =================================================================== --- monitor/monitor/asm.h (nonexistent) +++ monitor/monitor/asm.h (revision 16) @@ -0,0 +1,13 @@ +/* + * asm.h -- assembler + */ + + +#ifndef _ASM_H_ +#define _ASM_H_ + + +char *asmInstr(char *line, Word addr, Word *instrPtr); + + +#endif /* _ASM_H_ */ Index: monitor/monitor/end.s =================================================================== --- monitor/monitor/end.s (nonexistent) +++ monitor/monitor/end.s (revision 16) @@ -0,0 +1,19 @@ +; +; end.s -- end-of-segment labels +; + + .export _ecode + .export _edata + .export _ebss + + .code + .align 4 +_ecode: + + .data + .align 4 +_edata: + + .bss + .align 4 +_ebss: Index: monitor/monitor/getline.c =================================================================== --- monitor/monitor/getline.c (nonexistent) +++ monitor/monitor/getline.c (revision 16) @@ -0,0 +1,136 @@ +/* + * getline.c -- line input + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "getline.h" + + +#define MAX_HISTORY 100 + + +static char history[MAX_HISTORY][80]; +static int historyIndex; /* next line to be written */ + + +/* + * Get a line from the console. + */ +char *getLine(char *prompt) { + static char line[80]; + int index; + int historyPointer; + char c; + int i; + + printf(prompt); + index = 0; + historyPointer = historyIndex; + while (1) { + c = getchar(); + switch (c) { + case '\r': + putchar('\n'); + line[index] = '\0'; + return line; + case '\b': + case 0x7F: + if (index == 0) { + break; + } + putchar('\b'); + putchar(' '); + putchar('\b'); + index--; + break; + case 'P' & ~0x40: + if (historyPointer == historyIndex) { + line[index] = '\0'; + strcpy(history[historyIndex], line); + } + i = historyPointer - 1; + if (i == -1) { + i = MAX_HISTORY - 1; + } + if (i == historyIndex) { + putchar('\a'); + break; + } + if (history[i][0] == '\0') { + putchar('\a'); + break; + } + historyPointer = i; + strcpy(line, history[historyPointer]); + printf("\r"); + for (i = 0; i < 79; i++) { + printf(" "); + } + printf("\r"); + printf(prompt); + printf(line); + index = strlen(line); + break; + case 'N' & ~0x40: + if (historyPointer == historyIndex) { + putchar('\a'); + break; + } + i = historyPointer + 1; + if (i == MAX_HISTORY) { + i = 0; + } + historyPointer = i; + strcpy(line, history[historyPointer]); + printf("\r"); + for (i = 0; i < 79; i++) { + printf(" "); + } + printf("\r"); + printf(prompt); + printf(line); + index = strlen(line); + break; + default: + if (c == '\t') { + c = ' '; + } + if (c < 0x20 || c > 0x7E) { + break; + } + putchar(c); + line[index++] = c; + break; + } + } + /* never reached */ + return NULL; +} + + +/* + * Add a line to the history. + * Don't do this if the line is empty, or if its + * contents exactly match the previous line. + */ +void addHist(char *line) { + int lastWritten; + + if (*line == '\0') { + return; + } + lastWritten = historyIndex - 1; + if (lastWritten == -1) { + lastWritten = MAX_HISTORY - 1; + } + if (strcmp(history[lastWritten], line) == 0) { + return; + } + strcpy(history[historyIndex], line); + if (++historyIndex == MAX_HISTORY) { + historyIndex = 0; + } +} Index: monitor/monitor/cpu.c =================================================================== --- monitor/monitor/cpu.c (nonexistent) +++ monitor/monitor/cpu.c (revision 16) @@ -0,0 +1,367 @@ +/* + * cpu.c -- execute instructions + */ + + +#include "common.h" +#include "stdarg.h" +#include "romlib.h" +#include "instr.h" +#include "cpu.h" +#include "mmu.h" +#include "start.h" + + +#define RR(n) r[n] +#define WR(n,d) ((void) ((n) != 0 ? r[n] = (d) : (d))) + +#define BREAK (OP_TRAP << 26) + + +/**************************************************************/ + + +static Word pc; /* program counter */ +static Word psw; /* processor status word */ +static Word r[32]; /* general purpose registers */ + +static Bool breakSet; /* breakpoint set if true */ +static Word breakAddr; /* if breakSet, this is where */ + + +/**************************************************************/ + + +Word cpuGetPC(void) { + return pc; +} + + +void cpuSetPC(Word addr) { + pc = addr; +} + + +Word cpuGetReg(int regnum) { + return RR(regnum & 0x1F); +} + + +void cpuSetReg(int regnum, Word value) { + WR(regnum & 0x1F, value); +} + + +Word cpuGetPSW(void) { + return psw; +} + + +void cpuSetPSW(Word value) { + psw = value; +} + + +Bool cpuTestBreak(void) { + return breakSet; +} + + +Word cpuGetBreak(void) { + return breakAddr; +} + + +void cpuSetBreak(Word addr) { + breakAddr = addr; + breakSet = true; +} + + +void cpuResetBreak(void) { + breakSet = false; +} + + +/**************************************************************/ + + +static char *cause[32] = { + /* 0 */ "terminal 0 transmitter interrupt", + /* 1 */ "terminal 0 receiver interrupt", + /* 2 */ "terminal 1 transmitter interrupt", + /* 3 */ "terminal 1 receiver interrupt", + /* 4 */ "keyboard interrupt", + /* 5 */ "unknown interrupt", + /* 6 */ "unknown interrupt", + /* 7 */ "unknown interrupt", + /* 8 */ "disk interrupt", + /* 9 */ "unknown interrupt", + /* 10 */ "unknown interrupt", + /* 11 */ "unknown interrupt", + /* 12 */ "unknown interrupt", + /* 13 */ "unknown interrupt", + /* 14 */ "timer interrupt", + /* 15 */ "unknown interrupt", + /* 16 */ "bus timeout exception", + /* 17 */ "illegal instruction exception", + /* 18 */ "privileged instruction exception", + /* 19 */ "divide instruction exception", + /* 20 */ "trap instruction exception", + /* 21 */ "TLB miss exception", + /* 22 */ "TLB write exception", + /* 23 */ "TLB invalid exception", + /* 24 */ "illegal address exception", + /* 25 */ "privileged address exception", + /* 26 */ "unknown exception", + /* 27 */ "unknown exception", + /* 28 */ "unknown exception", + /* 29 */ "unknown exception", + /* 30 */ "unknown exception", + /* 31 */ "unknown exception" +}; + + +char *exceptionToString(int exception) { + if (exception < 0 || + exception >= sizeof(cause)/sizeof(cause[0])) { + return ""; + } + return cause[exception]; +} + + +/**************************************************************/ + + +static Byte stepType[64] = { + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 0x20 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 3, 4, 1, 0, + /* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + + +static Bool evalCond(int cc, Word a, Word b) { + switch (cc) { + case 0: + /* equal */ + if (a == b) { + return true; + } + break; + case 1: + /* not equal */ + if (a != b) { + return true; + } + break; + case 2: + /* less or equal (signed) */ + if ((signed int) a <= (signed int) b) { + return true; + } + break; + case 3: + /* less or equal (unsigned) */ + if (a <= b) { + return true; + } + break; + case 4: + /* less than (signed) */ + if ((signed int) a < (signed int) b) { + return true; + } + break; + case 5: + /* less than (unsigned) */ + if (a < b) { + return true; + } + break; + case 6: + /* greater or equal (signed) */ + if ((signed int) a >= (signed int) b) { + return true; + } + break; + case 7: + /* greater or equal (unsigned) */ + if (a >= b) { + return true; + } + break; + case 8: + /* greater than (signed) */ + if ((signed int) a > (signed int) b) { + return true; + } + break; + case 9: + /* greater than (unsigned) */ + if (a > b) { + return true; + } + break; + default: + printf("cannot compute condition code %d\n", cc); + break; + } + return false; +} + + +Bool cpuStep(void) { + Word instr; + int opcode; + int reg1, reg2; + Half immed; + Word offset; + Bool canStep; + Word nextAddr; + Word nextInstr; + int i; + MonitorState stepState; + MonitorState *origReturn; + + instr = mmuReadWord(pc); + opcode = (instr >> 26) & 0x3F; + reg1 = (instr >> 21) & 0x1F; + reg2 = (instr >> 16) & 0x1F; + immed = instr & 0x0000FFFF; + offset = instr & 0x03FFFFFF; + canStep = true; + switch (stepType[opcode]) { + case 1: + /* next instruction follows current one */ + nextAddr = pc + 4; + break; + case 2: + /* next instruction conditionally reached by PC relative branch */ + nextAddr = pc + 4; + if (evalCond(opcode - OP_BEQ, RR(reg1), RR(reg2))) { + nextAddr += SEXT16(immed) << 2; + } + break; + case 3: + /* next instruction reached by PC relative jump */ + nextAddr = pc + 4 + (SEXT26(offset) << 2); + break; + case 4: + /* next instruction reached by jump to register contents */ + nextAddr = RR(reg1); + break; + default: + printf("cannot single-step instruction with opcode 0x%02X\n", + opcode); + canStep = false; + break; + } + if (!canStep) { + return false; + } + nextInstr = mmuReadWord(nextAddr); + mmuWriteWord(nextAddr, BREAK); + for (i = 0; i < 32; i++) { + userContext.reg[i] = RR(i); + } + userContext.reg[30] = pc; + userContext.psw = psw & ~PSW_V; + userContext.tlbIndex = mmuGetIndex(); + userContext.tlbHi = mmuGetEntryHi(); + userContext.tlbLo = mmuGetEntryLo(); + if (saveState(&stepState)) { + origReturn = monitorReturn; + monitorReturn = &stepState; + resume(); + } + monitorReturn = origReturn; + for (i = 0; i < 32; i++) { + WR(i, userContext.reg[i]); + } + pc = userContext.reg[30]; + psw = userContext.psw | (psw & PSW_V); + mmuSetIndex(userContext.tlbIndex); + mmuSetEntryHi(userContext.tlbHi); + mmuSetEntryLo(userContext.tlbLo); + mmuWriteWord(nextAddr, nextInstr); + if (nextAddr == pc) { + return true; + } + if ((psw & PSW_V) == 0) { + printf("unexpected %s occurred\n", + exceptionToString((psw & PSW_PRIO_MASK) >> 16)); + return false; + } + if ((psw & PSW_PRIO_MASK) >> 16 == 21 && + (mmuGetEntryHi() & 0x80000000) == 0) { + pc = 0xC0000008; + } else { + pc = 0xC0000004; + } + return true; +} + + +Bool cpuRun(void) { + Word instr; + int i; + MonitorState runState; + MonitorState *origReturn; + + if (breakSet && breakAddr == pc) { + /* single-step one instruction */ + if (!cpuStep()) { + return false; + } + } + while (1) { + if (breakSet) { + instr = mmuReadWord(breakAddr); + mmuWriteWord(breakAddr, BREAK); + } + for (i = 0; i < 32; i++) { + userContext.reg[i] = RR(i); + } + userContext.reg[30] = pc; + userContext.psw = psw & ~PSW_V; + userContext.tlbIndex = mmuGetIndex(); + userContext.tlbHi = mmuGetEntryHi(); + userContext.tlbLo = mmuGetEntryLo(); + if (saveState(&runState)) { + origReturn = monitorReturn; + monitorReturn = &runState; + resume(); + } + monitorReturn = origReturn; + for (i = 0; i < 32; i++) { + WR(i, userContext.reg[i]); + } + pc = userContext.reg[30]; + psw = userContext.psw | (psw & PSW_V); + mmuSetIndex(userContext.tlbIndex); + mmuSetEntryHi(userContext.tlbHi); + mmuSetEntryLo(userContext.tlbLo); + if (breakSet) { + mmuWriteWord(breakAddr, instr); + } + if (breakSet && breakAddr == pc) { + return true; + } + if ((psw & PSW_V) == 0) { + printf("unexpected %s occurred\n", + exceptionToString((psw & PSW_PRIO_MASK) >> 16)); + return false; + } + if ((psw & PSW_PRIO_MASK) >> 16 == 21 && + (mmuGetEntryHi() & 0x80000000) == 0) { + pc = 0xC0000008; + } else { + pc = 0xC0000004; + } + } + /* never reached */ + return false; +} Index: monitor/monitor/sctio-ser.s =================================================================== --- monitor/monitor/sctio-ser.s (nonexistent) +++ monitor/monitor/sctio-ser.s (revision 16) @@ -0,0 +1,200 @@ +; +; sctio-ser.s -- disk sector I/O for disk made available by serial interface +; + +;*************************************************************** + + .export sctcapser ; determine disk capacity + .export sctioser ; do disk I/O + + .import ser1in + .import ser1out + .import ser1inchk + .import puts + + ; constants for communication with disk server + .set SYN,0x16 ; to initiate the three-way handshake + .set ACK,0x06 ; acknowledgement for handshake + .set RESULT_OK,0x00 ; server successfully executed cmd + ; everything else means error + + .set WAIT_DELAY,800000 ; count for delay loop + +;*************************************************************** + + .code + .align 4 + +sctcapser: + sub $29,$29,16 + stw $16,$29,0 + stw $17,$29,4 + stw $18,$29,8 + stw $31,$29,12 + add $4,$0,trymsg ; say what we are doing + jal puts + add $18,$0,$0 ; capacity == 0 if disk not present + add $16,$0,10 ; 10 tries to get a connection +handshake1: + sub $16,$16,1 + add $4,$0,SYN + jal ser1out ; send SYN + add $17,$0,WAIT_DELAY ; wait for ACK +handshake2: + sub $17,$17,1 + jal ser1inchk + bne $2,$0,handshake3 + bne $17,$0,handshake2 + add $4,$0,timeoutmsg + jal puts + bne $16,$0,handshake1 + add $4,$0,frustratedmsg + jal puts + j sctcapx +handshake3: + jal ser1in + add $8,$0,ACK + bne $2,$8,sctcapx + ; we got an ACK so we return it + add $4,$0,ACK + jal ser1out + + ; ask it for its capacity + add $4,$0,'c' + jal ser1out ; request + jal ser1in ; first byte of response + bne $2,$0,sctcapx ; exit if error + + ; all is well and the server will give us the capacity + add $16,$0,4 ; 4 bytes to read +sctcap1: + sll $18,$18,8 + jal ser1in + or $18,$18,$2 ; most significant byte first + sub $16,$16,1 + bne $16,$0,sctcap1 + + ; return value is in $18 +sctcapx: + add $2,$0,$18 + ldw $16,$29,0 + ldw $17,$29,4 + ldw $18,$29,8 + ldw $31,$29,12 + add $29,$29,16 + jr $31 + + .data + .align 4 + +trymsg: + .byte "Trying to connect to disk server..." + .byte 0x0A, 0 + +timeoutmsg: + .byte "Request timed out..." + .byte 0x0A, 0 + +frustratedmsg: + .byte "Unable to establish connection to disk server." + .byte 0x0A, 0 + + .code + .align 4 + +sctioser: + sub $29,$29,24 + stw $16,$29,0 + stw $17,$29,4 + stw $18,$29,8 + stw $19,$29,12 + stw $20,$29,16 + stw $31,$29,20 + add $16,$0,$4 ; command + add $17,$0,$5 ; start at sector + add $8,$0,0xc0000000 + or $18,$8,$6 ; memory address (logicalized) + add $19,$0,$7 ; number of sectors + + ; switch over command + add $8,$0,'r' + beq $8,$16,sctior ; read + add $8,$0,'w' + beq $8,$16,sctiow ; write + ; unknown command + add $2,$0,1 ; value != 0 signifies error + j sctiox + + ; read from disk +sctior: +sctior1: ; loop over number of sectors + beq $19,$0,sctiorsuc ; successful return + sub $19,$19,1 + ; read a sector + add $4,$0,'r' + jal ser1out + ; send sector number + add $20,$0,32 ; 4 bytes +sctior2: + sub $20,$20,8 + slr $4,$17,$20 + and $4,$4,0xff + jal ser1out + bne $20,$0,sctior2 + add $17,$17,1 + ; get answer + jal ser1in + bne $2,$0,sctiox ; $2 != 0 so we use it as return code + ; read data + add $20,$0,512 +sctior3: + sub $20,$20,1 + jal ser1in + stb $2,$18,0 + add $18,$18,1 + bne $20,$0,sctior3 + j sctior1 +sctiorsuc: + add $2,$0,$0 + j sctiox + + ; write to disk +sctiow: +sctiow1: ; loop over number of sectors + beq $19,$0,sctiowsuc ; successful return + sub $19,$19,1 + ; write a sector + add $4,$0,'w' + jal ser1out + ; send sector number + add $20,$0,32 ; 4 bytes +sctiow2: + sub $20,$20,8 + slr $4,$17,$20 + and $4,$4,0xff + jal ser1out + bne $20,$0,sctiow2 + add $17,$17,1 + ; write data + add $20,$0,512 +sctiow3: + sub $20,$20,1 + ldbu $4,$18,0 + jal ser1out + add $18,$18,1 + bne $20,$0,sctiow3 + ; get answer + jal ser1in + bne $2,$0,sctiox + j sctiow1 +sctiowsuc: + add $2,$0,$0 +sctiox: + ldw $16,$29,0 + ldw $17,$29,4 + ldw $18,$29,8 + ldw $19,$29,12 + ldw $20,$29,16 + ldw $31,$29,20 + add $29,$29,24 + jr $31 Index: monitor/monitor/stdarg.h =================================================================== --- monitor/monitor/stdarg.h (nonexistent) +++ monitor/monitor/stdarg.h (revision 16) @@ -0,0 +1,41 @@ +/* + * stdarg.h -- variable argument lists + */ + + +#ifndef _STDARG_H_ +#define _STDARG_H_ + + +typedef char *va_list; + + +static float __va_arg_tmp; + + +#define va_start(list, start) \ + ((void)((list) = (sizeof(start)<4 ? \ + (char *)((int *)&(start)+1) : (char *)(&(start)+1)))) + +#define __va_arg(list, mode, n) \ + (__typecode(mode)==1 && sizeof(mode)==4 ? \ + (__va_arg_tmp = *(double *)(&(list += \ + ((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \ + *(mode *)&__va_arg_tmp) : \ + *(mode *)(&(list += \ + ((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)])) + +#define _bigendian_va_arg(list, mode, n) \ + (sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \ + sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \ + __va_arg(list, mode, n)) + +#define va_end(list) ((void)0) + +#define va_arg(list, mode) \ + (sizeof(mode)==8 ? \ + *(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \ + _bigendian_va_arg(list, mode, 3U)) + + +#endif /* _STDARG_H_ */ Index: monitor/monitor/romlib.h =================================================================== --- monitor/monitor/romlib.h (nonexistent) +++ monitor/monitor/romlib.h (revision 16) @@ -0,0 +1,34 @@ +/* + * romlib.h -- the ROM library + */ + + +#ifndef _ROMLIB_H_ +#define _ROMLIB_H_ + + +void debugBreak(void); + +int strlen(const char *s); +int strcmp(const char *s, const char *t); +char *strcpy(char *s, const char *t); +char *strcat(char *s, const char *t); +char *strchr(const char *s, char c); +char *strtok(char *s, const char *t); + +unsigned long strtoul(const char *s, char **endp, int base); + +void qsort(void *base, int n, int size, + int (*cmp)(const void *, const void *)); + +char getchar(void); +void putchar(char c); +void puts(const char *s); + +int vprintf(const char *fmt, va_list ap); +int printf(const char *fmt, ...); +int vsprintf(char *s, const char *fmt, va_list ap); +int sprintf(char *s, const char *fmt, ...); + + +#endif /* _ROMLIB_H_ */ Index: monitor/monitor/getline.h =================================================================== --- monitor/monitor/getline.h (nonexistent) +++ monitor/monitor/getline.h (revision 16) @@ -0,0 +1,14 @@ +/* + * getline.h -- line input + */ + + +#ifndef _GETLINE_H_ +#define _GETLINE_H_ + + +char *getLine(char *prompt); +void addHist(char *line); + + +#endif /* _GETLINE_H_ */ Index: monitor/monitor/cpu.h =================================================================== --- monitor/monitor/cpu.h (nonexistent) +++ monitor/monitor/cpu.h (revision 16) @@ -0,0 +1,40 @@ +/* + * cpu.h -- execute instructions + */ + + +#ifndef _CPU_H_ +#define _CPU_H_ + + +#define PSW_V 0x08000000 /* interrupt vector bit in PSW */ +#define PSW_UM 0x04000000 /* user mode enable bit in PSW */ +#define PSW_PUM 0x02000000 /* previous value of PSW_UM */ +#define PSW_OUM 0x01000000 /* old value of PSW_UM */ +#define PSW_IE 0x00800000 /* interrupt enable bit in PSW */ +#define PSW_PIE 0x00400000 /* previous value of PSW_IE */ +#define PSW_OIE 0x00200000 /* old value of PSW_IE */ +#define PSW_PRIO_MASK 0x001F0000 /* bits to encode IRQ prio in PSW */ + + +Word cpuGetPC(void); +void cpuSetPC(Word addr); + +Word cpuGetReg(int regnum); +void cpuSetReg(int regnum, Word value); + +Word cpuGetPSW(void); +void cpuSetPSW(Word value); + +Bool cpuTestBreak(void); +Word cpuGetBreak(void); +void cpuSetBreak(Word addr); +void cpuResetBreak(void); + +char *exceptionToString(int exception); + +Bool cpuStep(void); +Bool cpuRun(void); + + +#endif /* _CPU_H_ */ Index: monitor/monitor/Makefile =================================================================== --- monitor/monitor/Makefile (nonexistent) +++ monitor/monitor/Makefile (revision 16) @@ -0,0 +1,31 @@ +# +# Makefile for ECO32 ROM monitor +# + +BUILD = ../../build + +SRC = start.s main.c command.c instr.c asm.c disasm.c \ + boot.c cpu.c mmu.c getline.c romlib.c \ + keyboard.s ../kbdtbls/kbdtbls.s display.s \ + serial.s sctio-ctl.s sctio-ser.s end.s + +.PHONY: all install clean + +all: monitor.bin monitor.exo + +install: monitor.bin monitor.exo + mkdir -p $(BUILD)/monitor + cp monitor.bin $(BUILD)/monitor + cp monitor.exo $(BUILD)/monitor + +monitor.exo: monitor.bin + $(BUILD)/bin/bin2exo 0 monitor.bin monitor.exo + +monitor.bin: $(SRC) + $(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \ + -Wl-m -Wlmonitor.map -o monitor.bin $(SRC) + +clean: + rm -f *~ + rm -f monitor.map monitor.bin + rm -f monitor.exo Index: monitor/monitor/common.h =================================================================== --- monitor/monitor/common.h (nonexistent) +++ monitor/monitor/common.h (revision 16) @@ -0,0 +1,27 @@ +/* + * common.h -- common definitions + */ + + +#ifndef _COMMON_H_ +#define _COMMON_H_ + + +#define PAGE_SHIFT 12 /* log2 of page size */ +#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */ +#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */ +#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */ + + +typedef enum { false, true } Bool; /* truth values */ + + +typedef unsigned int Word; /* 32 bit quantities */ +typedef unsigned short Half; /* 16 bit quantities */ +typedef unsigned char Byte; /* 8 bit quantities */ + + +#define NULL ((void *) 0) + + +#endif /* _COMMON_H_ */ Index: monitor/Makefile =================================================================== --- monitor/Makefile (nonexistent) +++ monitor/Makefile (revision 16) @@ -0,0 +1,25 @@ +# +# Makefile for building the ECO32 ROM monitor +# + +BUILD = ../build + +DIRS = kbdtbls monitor + +.PHONY: all install clean + +all: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i all ; \ + done + +install: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i install ; \ + done + +clean: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i clean ; \ + done + rm -f *~ Index: Makefile =================================================================== --- Makefile (revision 15) +++ Makefile (revision 16) @@ -4,7 +4,7 @@ VERSION = 0.22 -DIRS = doc binutils sim simtest fpga hwtests +DIRS = doc binutils sim simtest fpga hwtests monitor BUILD = `pwd`/build .PHONY: all compiler builddir clean dist

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.