Beta Simulators (PDQ-3 and SAGE) from Holger Veit

This commit is contained in:
Mark Pizzolato 2014-09-17 17:31:40 -07:00
parent 7087f1e1c6
commit e2524e7feb
69 changed files with 24440 additions and 4 deletions

1
.gitattributes vendored
View file

@ -4,6 +4,7 @@
*.vcproj binary
*.exe binary
*.bin binary
*.imd binary
*.rim binary
sim_rev.h export-subst

BIN
PDQ-3/hdt/CPU_C5.bin Normal file

Binary file not shown.

BIN
PDQ-3/master.imd Normal file

Binary file not shown.

174
PDQ-3/names.sim Normal file
View file

@ -0,0 +1,174 @@
name CSP:proc53 initdriver
name CSP:proc52 ExtractSegno
name CSP:proc51 getsib
name CSP:proc50 myselfer
name CSP:proc49 S_IOR_Set
name CSP:proc48 S_Read_Seg
name CSP:proc47 S_Chuck_G_Dir
name CSP:proc46 S_Finish_CU
name CSP:proc45 S_Execute_CU
name CSP:proc44 S_Geq_U
name CSP:proc43 S_Blow_Up
name CSP:proc42 S_Bump_Heap
name CSP:proc41 S_R_Mem_Avail
name CSP:proc40 S_Mem_Avail
name CSP:proc39 S_Halt
name CSP:proc38 S_Unit_Clear
name CSP:proc37 S_Unit_Wait
name CSP:proc36 S_Pwr_of_Ten
name CSP:proc35 S_Unit_Busy
name CSP:proc34 S_Io_Result
name CSP:proc33 S_Release
name CSP:proc32 S_Mark
name CSP:proc31 X_Sqrt
name CSP:proc30 X_Exp
name CSP:proc29 X_Ln
name CSP:proc28 S_Unload_Seg
name CSP:proc27 S_Load_Seg
name CSP:proc26 S_Unit_Status
name CSP:proc25 X_Sin
name CSP:proc24 S_Blk_Exit
name CSP:proc23 S_Attach
name CSP:proc22 S_Rel_Seg
name CSP:proc21 S_Get_Seg
name CSP:proc20 S_Stop_P
name CSP:proc19 S_Start_P
name CSP:proc18 S_Check
name CSP:proc17 S_Assign
name CSP:proc16 S_Geq_S
name CSP:proc15 S_Leq_S
name CSP:proc14 S_Equ_S
name CSP:proc13 S_New
name CSP:proc12 S_IO_Check
name CSP:proc11 S_Scan
name CSP:proc10 S_Fill_Char
name CSP:proc9 S_Time
name CSP:proc8 S_Tree_Search
name CSP:proc17 S_Id_Search
name CSP:proc6 S_Unit_Write
name CSP:proc5 S_Unit_Read
name CSP:proc4 S_Exit
name CSP:proc3 S_Move_Right
name CSP:proc2 S_Move_Left
name CSP:proc1 csp_initunit
name GOTOXYU:proc1 gotoxyu_initunit
name GOTOXYU:proc2 Z19_XY
name PASCALIO:proc1 pascalio_initunit
name PASCALIO:proc2 F_Read_Real
name PASCALIO:proc3 F_Write_Real
name PASCALIO:proc4 F_Seek
name LONGINT:proc1 longint_initunit
name LONGINT:proc2 F_Read_Dec
name LONGINT:proc3 F_Write_Dec
name LONGINT:proc4 Decops
name TRANSCEN:proc1 transcen_initunit
name TRANSCEN:proc2 S_Sin
name TRANSCEN:proc3 S_Cos
name TRANSCEN:proc4 S_Log10
name TRANSCEN:proc5 S_Arctan
name TRANSCEN:proc6 S_Ln
name TRANSCEN:proc7 S_Exp
name TRANSCEN:proc8 S_Sqrt
name HEAPOPS:proc1 heapops_initunit
name HEAPOPS:proc2 H_Mark
name HEAPOPS:proc3 H_Release
name HEAPOPS:proc4 H_New
name HEAPOPS:proc5 H_Dispose
name HEAPOPS:proc6 H_Mem_Lock
name HEAPOPS:proc7 H_Mem_Swap
name HEAPOPS:proc8 H_Var_New
name HEAPOPS:proc9 H_Var_Dispose
name HEAPOPS:proc10 H_Var_Avail
name HEAPOPS:proc11 H_Unlock_Seg
name HEAPOPS:proc12 H_Clean_Up
name EXCEPTIO:proc1 exceptio_initunit
name EXCEPTIO:proc2 Handle_Exception
name EXCEPTIN:proc1 exceptin_initunit
name EXCEPTIN:proc2 Ex_Stats
name HALTUNIT:proc1 haltunit_initunit
name HALTUNIT:proc2 Do_Halt
name CLOCKDRI:proc1 clockdri_initunit
name CLOCKDRI:proc2 Clk_Init
name CLOCKDRI:proc3 Clk_Read
name CLOCKDRI:proc4 Clk_Write
name CLOCKDRI:proc5 Clk_Clear
name CLOCKDRI:proc6 Clk_Power
name CLOCKDRI:proc7 Clk_Status
name CLOCKDRI:proc8 Clk_Term
name DTCDRIVE:proc1 dtcdrive_initunit
name DTCDRIVE:proc2 Dtc_Init
name DTCDRIVE:proc3 Dtc_Read
name DTCDRIVE:proc4 Dtc_Write
name DTCDRIVE:proc5 Dtc_Clear
name DTCDRIVE:proc6 Dtc_Power
name DTCDRIVE:proc7 Dtc_Status
name DTCDRIVE:proc8 Dtc_Term
name DZ11DRIV:proc1 dz11driv_initunit
name DZ11DRIV:proc2 DZ_Init
name DZ11DRIV:proc3 DZ_Read
name DZ11DRIV:proc4 DZ_Write
name DZ11DRIV:proc5 DZ_Clear
name DZ11DRIV:proc6 DZ_Power
name DZ11DRIV:proc7 DZ_Status
name DZ11DRIV:proc8 DZ_Term
name FLOPPYDR:proc1 floppydr_initunit
name FLOPPYDR:proc2 Fl_Init
name FLOPPYDR:proc3 Fl_Read
name FLOPPYDR:proc4 Fl_Write
name FLOPPYDR:proc5 Fl_Clear
name FLOPPYDR:proc6 Fl_Power
name FLOPPYDR:proc7 Fl_Status
name FLOPPYDR:proc8 Fl_Term
name PRIAMDRI:proc1 priamdri_initunit
name PRIAMDRI:proc2 Prm_Init
name PRIAMDRI:proc3 Prm_Read
name PRIAMDRI:proc4 Prm_Write
name PRIAMDRI:proc5 Prm_Clear
name PRIAMDRI:proc6 Prm_Power
name PRIAMDRI:proc7 Prm_Status
name PRIAMDRI:proc8 Prm_Term
name RL02DRIV:proc1 rl02driv_initunit
name RL02DRIV:proc2 RL_Init
name RL02DRIV:proc3 RL_Read
name RL02DRIV:proc4 RL_Write
name RL02DRIV:proc5 RL_Clear
name RL02DRIV:proc6 RL_Power
name RL02DRIV:proc7 RL_Status
name RL02DRIV:proc8 RL_Term
name SERDRIVE:proc1 serdrive_initunit
name SERDRIVE:proc2 Ser_Init
name SERDRIVE:proc3 Ser_Read
name SERDRIVE:proc4 Ser_Write
name SERDRIVE:proc5 Ser_Clear
name SERDRIVE:proc6 Ser_Power
name SERDRIVE:proc7 Ser_Status
name SERDRIVE:proc8 Ser_Term
name STANDRIV:proc1 standriv_initunit
name STANDRIV:proc2 Stan_Init
name STANDRIV:proc3 Stan_Read
name STANDRIV:proc4 Stan_Write
name STANDRIV:proc5 Stan_Clear
name STANDRIV:proc6 Stan_Power
name STANDRIV:proc7 Stan_Status
name STANDRIV:proc8 Stan_Term
name SYSDRIVE:proc1 sysdrive_initunit
name SYSDRIVE:proc2 Intr_Init
name SYSDRIVE:proc3 Intr_Enable
name SYSDRIVE:proc4 Enter_HDT
name TM11DRIV:proc1 standriv_initunit
name TM11DRIV:proc2 TM_Init
name TM11DRIV:proc3 TM_Read
name TM11DRIV:proc4 TM_Write
name TM11DRIV:proc5 TM_Clear
name TM11DRIV:proc6 TM_Power
name TM11DRIV:proc7 TM_Status
name TM11DRIV:proc8 TM_Term
name SPOOLUNI:proc1 spooluni_initunit
name SPOOLUNI:proc2 Spool_Status
name SPOOLUNI:proc3 Spool_Restart
name SPOOLUNI:proc4 Spool_Stop
name SPOOLUNI:proc5 Spool_File
name SHELL:proc1 SHELL_initunit
name GETCMD:proc1 GETCMD_initunit
name SERDRIVE:proc9 SER_EnDis_RCVXMIT
name SERDRIVE:proc16 SER_RawEmit

232
PDQ-3/opcode.dbg Normal file
View file

@ -0,0 +1,232 @@
0 0 ;SLDC0
1 0 ;SLDC1
2 0 ;SLDC2
3 0 ;SLDC3
4 0 ;SLDC4
5 0 ;SLDC5
6 0 ;SLDC6
7 0 ;SLDC7
8 0 ;SLDC8
9 0 ;SLDC9
a 0 ;SLDC10
b 0 ;SLDC11
c 0 ;SLDC12
d 0 ;SLDC13
e 0 ;SLDC14
f 0 ;SLDC15
10 0 ;SLDC16
11 0 ;SLDC17
12 0 ;SLDC18
13 0 ;SLDC19
14 0 ;SLDC20
15 0 ;SLDC21
16 0 ;SLDC22
17 0 ;SLDC23
18 0 ;SLDC24
19 0 ;SLDC25
1a 0 ;SLDC26
1b 0 ;SLDC27
1c 0 ;SLDC28
1d 0 ;SLDC29
1e 0 ;SLDC30
1f 0 ;SLDC31
20 0 ;SLDL1
21 0 ;SLDL2
22 0 ;SLDL3
23 0 ;SLDL4
24 0 ;SLDL5
25 0 ;SLDL6
26 0 ;SLDL7
27 0 ;SLDL8
28 0 ;SLDL9
29 0 ;SLDL10
2a 0 ;SLDL11
2b 0 ;SLDL12
2c 0 ;SLDL13
2d 0 ;SLDL14
2e 0 ;SLDL15
2f 0 ;SLDL16
30 0 ;SLDO1
31 0 ;SLDO2
32 0 ;SLDO3
33 0 ;SLDO4
34 0 ;SLDO5
35 0 ;SLDO6
36 0 ;SLDO7
37 0 ;SLDO8
38 0 ;SLDO9
39 0 ;SLDO10
3a 0 ;SLDO11
3b 0 ;SLDO12
3c 0 ;SLDO13
3d 0 ;SLDO14
3e 0 ;SLDO15
3f 0 ;SLDO16
40 3 ;
41 3 ;
42 3 ;
43 3 ;
44 3 ;
45 3 ;
46 3 ;
47 3 ;
48 3 ;
49 3 ;
4a 3 ;
4b 3 ;
4c 3 ;
4d 3 ;
4e 3 ;
4f 3 ;
50 3 ;
51 3 ;
52 3 ;
53 3 ;
54 3 ;
55 3 ;
56 3 ;
57 3 ;
58 3 ;
59 3 ;
5a 3 ;
5b 3 ;
5c 3 ;
5d 3 ;
5e 3 ;
5f 3 ;
60 3 ;
61 3 ;
62 3 ;
63 3 ;
64 3 ;
65 3 ;
66 3 ;
67 3 ;
68 3 ;
69 3 ;
6a 3 ;
6b 3 ;
6c 3 ;
6d 3 ;
6e 3 ;
6f 3 ;
70 3 ;
71 3 ;
72 3 ;
73 3 ;
74 3 ;
75 3 ;
76 3 ;
77 3 ;
78 0 ;SIND0
79 0 ;SIND1
7a 0 ;SIND2
7b 0 ;SIND3
7c 0 ;SIND4
7d 0 ;SIND5
7e 0 ;SIND6
7f 0 ;SIND7
80 0 ;LDCB
81 0 ;LDCI
82 0 ;LCA
83 0 ;LDC
84 0 ;LLA
85 3 ;LDO
86 0 ;LAO
87 0 ;LDL
88 0 ;LDA
89 0 ;LOD
8a 0 ;UJP
8b 0 ;UJPL
8c 0 ;MPI
8d 0 ;DVI
8e 0 ;STM
8f 0 ;MODI
90 0 ;CPL
91 0 ;CPG
92 0 ;CPI
93 0 ;CXL
94 0 ;CXG
95 0 ;CXI
96 0 ;RPU
97 0 ;CPF
98 0 ;LDCN
99 0 ;LSL
9a 3 ;LDE
9b 3 ;LAE
9c 0 ;NOP
9d 0 ;LPR
9e 3 ;BPT
9f 0 ;BNOT
a0 0 ;LOR
a1 0 ;LAND
a2 0 ;ADI
a3 0 ;SBI
a4 0 ;STL
a5 0 ;SRO
a6 0 ;STR
a7 0 ;LDB
a8 3 ;
a9 3 ;
aa 3 ;
ab 3 ;
ac 3 ;
ad 3 ;
ae 3 ;
af 3 ;
b0 0 ;EQUI
b1 0 ;NEQI
b2 0 ;LEQI
b3 0 ;GEQI
b4 0 ;LEUSW
b5 0 ;GEUSW
b6 0 ;EQUPWR
b7 0 ;LEQPWR
b8 0 ;GEQPWR
b9 0 ;EQUBYT
ba 3 ;LEQBYT
bb 3 ;GEQBYT
bc 0 ;SRS
bd 3 ;SWAP
be 3 ;TNC
bf 3 ;RND
c0 3 ;ADR
c1 3 ;SBR
c2 3 ;MPR
c3 0 ;DVR
c4 0 ;STO
c5 0 ;MOV
c6 3 ;DUP2
c7 0 ;ADJ
c8 0 ;STB
c9 0 ;LDP
ca 0 ;STP
cb 0 ;CHK
cc 0 ;FLT
cd 0 ;EQUREAL
ce 0 ;LEQREAL
cf 3 ;GEQREAL
d0 0 ;LDM
d1 0 ;SPR
d2 3 ;EFJ
d3 3 ;NFJ
d4 0 ;FJP
d5 0 ;FJPL
d6 0 ;XJP
d7 0 ;IXA
d8 0 ;IXP
d9 3 ;STE
da 0 ;INN
db 0 ;UNI
dc 0 ;INT
dd 0 ;DIF
de 0 ;SIGNAL
df 0 ;WAIT
e0 3 ;ABI
e1 0 ;NGI
e2 0 ;DUP1
e3 3 ;ABR
e4 3 ;NGR
e5 0 ;LNOT
e6 0 ;IND
e7 0 ;INC

1733
PDQ-3/pdq3_cpu.c Normal file

File diff suppressed because it is too large Load diff

441
PDQ-3/pdq3_debug.c Normal file
View file

@ -0,0 +1,441 @@
/* pdq3_debug.c: PDQ3 debug helper
Work derived from Copyright (c) 2004-2012, Robert M. Supnik
Copyright (c) 2013 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of Robert M Supnik and Holger Veit
shall not be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik and Holger Veit.
20130421 hv initial version
20130928 hv fix problem with callstack when S_Start_P patches MSCW
20131012 hv view calltree returned incorrect segment of caller
*/
#include "pdq3_defs.h"
static uint8 *opdebug = NULL;
static void dbg_opdbgcreate() {
int i;
FILE *fd = fopen(DEBUG_OPDBGFILE, "w");
if (fd==NULL) {
fprintf(stderr,"Cannot create %s\n", DEBUG_OPDBGFILE);
exit(1);
}
for (i=DEBUG_MINOPCODE; i<DEBUG_MAXOPCODE; i++) {
if (DEBUG_VALIDOP(i)) {
fprintf(fd,"%x %d ;%s\n",
i, DEBUG_PRE|DEBUG_POST, optable[i].name);
} else {
fprintf(fd,"%x %d ;invalid\n",
i, DEBUG_PRE|DEBUG_POST);
}
}
fclose(fd);
fprintf(stderr,"%s created. Adapt file manually and restart simh\n", DEBUG_OPDBGFILE);
exit(2);
}
static void dbg_opdbginit() {
char line[100];
int i, f;
FILE* fd = fopen(DEBUG_OPDBGFILE,"r");
if (fd == NULL)
dbg_opdbgcreate(); /* will not return */
if (opdebug == NULL)
opdebug = (uint8*)calloc(DEBUG_MAXOPCODE-DEBUG_MINOPCODE,sizeof(uint8));
for (i=DEBUG_MINOPCODE; i<DEBUG_MAXOPCODE; i++)
opdebug[i-DEBUG_MINOPCODE] = DEBUG_PRE|DEBUG_POST;
while (!feof(fd)) {
fgets(line,100,fd);
sscanf(line,"%x %d", &i, &f);
opdebug[i-DEBUG_MINOPCODE] = f;
}
fclose(fd);
}
t_stat dbg_check(t_value op, uint8 flag) {
if (opdebug[op-DEBUG_MINOPCODE] & flag) {
if (flag & DEBUG_PRE) {
opdebug[op-DEBUG_MINOPCODE] &= ~DEBUG_PRE;
return STOP_DBGPRE;
} else
return STOP_DBGPOST;
}
return SCPE_OK;
}
t_stat dbg_dump_tib(FILE *fd, uint16 base) {
t_stat rc;
uint16 data;
fprintf(fd, "TIB at $%04x (CTP=$%04x, RQ=$%04x)\n",base, reg_ctp, reg_rq);
if ((rc=ReadEx(base, OFF_WAITQ, &data)) != SCPE_OK) return rc;
fprintf(fd, " WAITQ: $%04x\n",data);
if ((rc=ReadBEx(base+OFFB_PRIOR, 0, &data)) != SCPE_OK) return rc;
fprintf(fd, " PRIOR: %02x\n",data);
if ((rc=ReadEx(base, OFF_SPLOW, &data)) != SCPE_OK) return rc;
fprintf(fd, " SPLOW: $%04x\n",data);
if ((rc=ReadEx(base, OFF_SPUPR, &data)) != SCPE_OK) return rc;
fprintf(fd, " SPUPR: $%04x\n",data);
if ((rc=ReadEx(base, OFF_SP, &data)) != SCPE_OK) return rc;
fprintf(fd, " SP: $%04x\n",data);
if ((rc=ReadEx(base, OFF_MP, &data)) != SCPE_OK) return rc;
fprintf(fd, " MP: $%04x\n",data);
if ((rc=ReadEx(base, OFF_BP, &data)) != SCPE_OK) return rc;
fprintf(fd, " BP: $%04x\n",data);
if ((rc=ReadEx(base, OFF_IPC, &data)) != SCPE_OK) return rc;
fprintf(fd, " IPC: #%04x\n",data);
if ((rc=ReadEx(base, OFF_SEGB, &data)) != SCPE_OK) return rc;
fprintf(fd, " SEGB: $%04x\n",data);
if ((rc=ReadEx(base, OFF_HANGP, &data)) != SCPE_OK) return rc;
fprintf(fd, " HANGP: $%04x\n",data);
if ((rc=ReadEx(base, OFF_IORSLT, &data)) != SCPE_OK) return rc;
fprintf(fd, " IORSLT: %04x\n",data);
if ((rc=ReadEx(base, OFF_SIBS, &data)) != SCPE_OK) return rc;
fprintf(fd, " SIBS: $%04x\n",data);
return SCPE_OK;
}
t_stat dbg_dump_queue(FILE* fd, const char* qname, uint16 q) {
t_stat rc;
fprintf(fd, "dump queue %s: address=$%04x\n ",qname, q);
while (q != NIL) {
fprintf(fd, "$%04x->",q);
if ((rc=ReadEx(q, OFF_WAITQ, &q)) != SCPE_OK) return rc;
}
fprintf(fd, "NIL\n");
return SCPE_OK;
}
t_stat dbg_dump_mscw(FILE* fd, uint16 base) {
t_stat rc;
uint16 data;
fprintf(fd, "MSCW at $%04x\n",base);
if ((rc=ReadEx(base, OFF_MSSTAT, &data)) != SCPE_OK) return rc;
fprintf(fd, " MSSTAT: $%04x\n", data);
if ((rc=ReadEx(base, OFF_MSDYNL, &data)) != SCPE_OK) return rc;
fprintf(fd, " MSDYNL: $%04x\n", data);
if ((rc=ReadEx(base, OFF_MSIPC, &data)) != SCPE_OK) return rc;
fprintf(fd, " MSIPC: $%04x\n", data);
if ((rc=ReadBEx(base+OFFB_MSSEG, 0, &data)) != SCPE_OK) return rc;
fprintf(fd, " MSSEG: %02x\n", data);
return SCPE_OK;
}
void dbg_enable() {
cpu_dev.dctrl |= (DBG_CPU_READ|DBG_CPU_WRITE|DBG_CPU_STACK);
}
/******************************************************************************
* Segment Tracking support
*****************************************************************************/
static char* pdq3_segname(uint16 nameptr) {
static char name[10];
uint16 data;
int i;
for (i=0; i<8; i++) {
ReadBEx(nameptr,i,&data);
name[i] = data != ' ' ? data : 0;
}
name[8] = 0;
return name;
}
t_stat dbg_dump_seg(FILE* fd, uint16 segptr) {
t_stat rc;
uint16 data;
if ((rc=ReadEx(segptr, OFF_SEGBASE, &data)) != SCPE_OK) return rc;
fprintf(fd, " BASE: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGLENG, &data)) != SCPE_OK) return rc;
fprintf(fd, " LENGTH: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGREFS, &data)) != SCPE_OK) return rc;
fprintf(fd, " REFS: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGADDR, &data)) != SCPE_OK) return rc;
fprintf(fd, " ADDR: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGUNIT, &data)) != SCPE_OK) return rc;
fprintf(fd, " UNIT: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_PREVSP, &data)) != SCPE_OK) return rc;
fprintf(fd, " PREVSP: $%04x\n",data);
fprintf(fd, " NAME: %s\n", pdq3_segname(segptr+OFF_SEGNAME));
if ((rc=ReadEx(segptr, OFF_SEGLINK, &data)) != SCPE_OK) return rc;
fprintf(fd, " LINK: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGGLOBAL, &data)) != SCPE_OK) return rc;
fprintf(fd, " GLOBAL: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGINIT, &data)) != SCPE_OK) return rc;
fprintf(fd, " INIT: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEG13, &data)) != SCPE_OK) return rc;
fprintf(fd, " entry13: $%04x\n",data);
if ((rc=ReadEx(segptr, OFF_SEGBACK, &data)) != SCPE_OK) return rc;
fprintf(fd, " SELF: $%04x\n",data);
return SCPE_OK;
}
t_stat dbg_dump_segtbl(FILE* fd) {
int i;
uint16 segptr, nsegs;
t_stat rc;
if (reg_ssv < 0x2030 || reg_ssv > 0xf000) {
printf("Cannot list segments in bootloader: incomplete tables\n");
return SCPE_NXM;
}
if ((rc=Read(reg_ssv, -1, &nsegs, 0)) != SCPE_OK) return rc;
fprintf(fd, "Segment table: ssv=$%04x size=%d\n",reg_ssv, nsegs);
for (i=0; i<=nsegs; i++) {
if ((rc=ReadEx(reg_ssv, i, &segptr)) != SCPE_OK) return rc;
fprintf(fd, " %02x %04x %s\n",i,segptr, pdq3_segname(segptr + OFF_SEGNAME));
}
return SCPE_OK;
}
/* segment tracking */
typedef struct _seginfo {
uint16 base; /* base load address */
struct _seginfo* next;
uint16 idx; /* index into SSV table */
char name[10]; /* segment name */
uint16 size;
uint16 nproc;
uint16 segno;
} SEGINFO;
#define SEGHASHSIZE 97
SEGINFO* seghash[SEGHASHSIZE];
#define SEGHASHFUNC(i) (i % SEGHASHSIZE)
void dbg_segtrackinit() {
int i;
for (i=0; i<SEGHASHSIZE; i++)
seghash[i] = NULL;
}
static SEGINFO* new_seginfo(SEGINFO* next, uint16 base) {
SEGINFO* s = (SEGINFO*)malloc(sizeof(SEGINFO));
s->next = next;
s->base = base;
return s;
}
static SEGINFO* find_seginfo(uint16 base, int* idx) {
SEGINFO* s;
*idx = SEGHASHFUNC(base);
s = seghash[*idx];
while (s && s->base != base) s = s->next;
return s;
}
t_stat dbg_segtrack(uint16 segbase) {
t_stat rc;
int idx;
SEGINFO* s = find_seginfo(segbase, &idx);
if (!s) {
s = seghash[idx] = new_seginfo(seghash[idx], segbase);
if ((rc=ReadEx(segbase, 0, &s->size)) != SCPE_OK) return rc;
strcpy(s->name, segbase==0xf418 ? "HDT" : pdq3_segname(segbase+2));
if ((rc=ReadBEx(segbase+s->size, 0, &s->segno)) != SCPE_OK) return rc;
if ((rc=ReadBEx(segbase+s->size, 1, &s->nproc)) != SCPE_OK) return rc;
// printf("Entered at %04x: %s sz=%x seg=%x np=%x\n",segbase, s->name, s->size, s->segno, s->nproc);
}
return SCPE_OK;
}
/******************************************************************************
* Name Alias Handling
*****************************************************************************/
typedef struct _aliases {
char* key;
char* alias;
struct _aliases* next;
} ALIASES;
#define ALIASHASHSIZE 97
static ALIASES* aliases[ALIASHASHSIZE];
static void dbg_initaliases() {
int i;
for (i=0; i<ALIASHASHSIZE; i++)
aliases[i] = NULL;
}
static int aliashash(const char* key) {
int i, h=0;
int len = strlen(key);
for (i=0; i<len; i++)
h += key[i];
return h % ALIASHASHSIZE;
}
static ALIASES* find_alias(const char* key, int* idx) {
ALIASES* a;
char gbuf[CBUFSIZE], gbuf2[CBUFSIZE];
get_glyph(key, gbuf, 0);
*idx = aliashash(key);
a = aliases[*idx];
if (a) get_glyph(a->key, gbuf2, 0);
while (a && strcmp(gbuf2,gbuf)) {
a = a->next;
if (a) get_glyph(a->key, gbuf2, 0);
}
return a;
}
t_stat dbg_enteralias(const char* key, const char* value) {
int idx;
ALIASES* a = find_alias(key, &idx);
if (!a) {
a = (ALIASES*)malloc(sizeof(ALIASES));
a->key = strdup(key);
a->alias = strdup(value);
a->next = aliases[idx];
aliases[idx] = a;
}
return SCPE_OK;
}
t_stat dbg_listalias(FILE* fd) {
int i;
ALIASES* a;
fprintf(fd, "Name table:\n");
for (i=0; i<ALIASHASHSIZE; i++) {
a = aliases[i];
while (a) {
fprintf(fd, " Name %s = %s\n", a->key, a->alias);
a = a->next;
}
}
return SCPE_OK;
}
/******************************************************************************
* Procedure tracking support
*****************************************************************************/
typedef struct _procinfo {
struct _procinfo *next;
uint16 procno;
SEGINFO* seg;
uint16 localsz;
uint16 freesz;
uint16 mscw;
uint16 segb;
uint16 instipc;
uint16 ipc;
} PROCINFO;
const char* find_procname(PROCINFO* p) {
ALIASES* a;
int dummy;
static char buf[100];
sprintf(buf,"%s:proc%d", p->seg->name, p->procno);
a = find_alias(buf, &dummy);
if (a) return a->alias;
return buf;
}
static PROCINFO* procroot = NULL;
static PROCINFO* new_procinfo(uint16 segbase, uint16 procno, uint16 mscw, uint16 osegb) {
int dummy;
uint16 procbase, procaddr;
uint16 exitic, sz1, sz2;
PROCINFO* p = (PROCINFO*)malloc(sizeof(PROCINFO));
p->procno = procno;
p->mscw = mscw;
p->seg = find_seginfo(segbase, &dummy);
p->segb = osegb;
p->instipc = ADDR_OFF(PCX);
ReadEx(mscw,OFF_MSIPC, &p->ipc);
ReadEx(segbase, 0, &procbase);
ReadEx(segbase+procbase-procno, 0, &procaddr);
ReadEx(segbase+procaddr, 0, &p->localsz);
ReadEx(segbase+procaddr-1, 0, &exitic);
ReadBEx(segbase, exitic, &sz1);
if (sz1==0x96) {
ReadBEx(segbase, exitic+1, &sz1);
if (sz1 & 0x80) {
ReadBEx(segbase, exitic+2, &sz2);
sz1 = ((sz1 & 0x7f)<<8) | sz2;
}
p->freesz = sz1;
}
return p;
}
t_stat dbg_procenter(uint16 segbase, uint16 procno, uint16 mscw, uint16 osegb) {
PROCINFO* p = new_procinfo(segbase, procno, mscw, osegb);
p->next = procroot;
procroot = p;
return SCPE_OK;
}
t_stat dbg_procleave() {
t_stat rc;
PROCINFO* p = procroot;
uint16 ipc,pipc;
while (p) {
pipc = p->ipc;
if ((rc=ReadEx(p->mscw,OFF_MSIPC, &ipc)) != SCPE_OK) return rc;
procroot = p->next;
free(p);
if (pipc == ipc) break;
p = procroot;
}
return SCPE_OK;
}
t_stat dbg_calltree(FILE* fd) {
PROCINFO* p = procroot, *lastp;
if (!p) {
fprintf(fd,"Callstack is empty\n");
return SCPE_OK;
}
fprintf(fd,"Calltree:\nCurrently in %s at %04x:%04x\n",
find_procname(p), reg_segb, reg_ipc);
lastp = p;
p = p->next;
while (p) {
fprintf(fd," at %04x:%04x called by %s (%04x:%04x)\n",
lastp->segb, lastp->instipc, find_procname(p), p->segb, p->instipc);
lastp = p;
p = p->next;
}
return SCPE_OK;
}
/******************************************************************************
* Initialization
*****************************************************************************/
t_stat dbg_init() {
dbg_opdbginit();
dbg_segtrackinit();
return SCPE_OK;
}

415
PDQ-3/pdq3_defs.h Normal file
View file

@ -0,0 +1,415 @@
/* pdq3_defs.h: PDQ3 simulator definitions
Work derived from Copyright (c) 2004-2012, Robert M. Supnik
Copyright (c) 2013 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of Robert M Supnik and Holger Veit
shall not be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik and Holger Veit.
20131103 hv INT_CONR/CONT assignments incorrect in docs, must be swapped
*/
#ifndef _PDQ3_DEFS_H_
#define _PDQ3_DEFS_H_ 0
#include "sim_defs.h" /* simulator defns */
#include "sim_sock.h"
#include "sim_tmxr.h"
/* constants */
#define NIL 0xfc00 /* Pascal Microengine NIL value */
#define MSCW_SZ 4 /* size of MSCW */
#define REAL_SZ 2 /* size of real number (REAL*4) */
#define BSET_SZ 4080 /* usable size of set in bits */
#define ISET_SZ 255 /* size of set in words */
#define WORD_SZ 16 /* size of machine word in bits */
#define OFF_SEGBASE 0 /* offsets into SIB entry */
#define OFF_SEGLENG 1
#define OFF_SEGREFS 2
#define OFF_SEGADDR 3
#define OFF_SEGUNIT 4
#define OFF_PREVSP 5
#define OFF_SEGNAME 6
#define OFF_SEGLINK 10
#define OFF_SEGGLOBAL 11
#define OFF_SEGINIT 12
#define OFF_SEG13 13
#define OFF_SEGBACK 14
#define OFF_MSSTAT 0 /* offsets into MSCW */
#define OFF_MSDYNL 1
#define OFF_MSIPC 2
#define OFFB_MSSEG 3
#define OFFB_MSFLAG 3
#define OFF_WAITQ 0 /* offset into TIB */
#define OFF_QLINK 0
#define OFFB_PRIOR 1
#define OFFB_FLAGS 1
#define OFF_SPLOW 2
#define OFF_SPUPR 3
#define OFF_SP 4
#define OFF_MP 5
#define OFF_BP 6
#define OFF_IPC 7
#define OFF_SEGB 8
#define OFF_HANGP 9
#define OFF_IORSLT 10
#define OFF_SIBS 11
#define OFF_SEMCOUNT 0 /* offset into SEMA variable */
#define OFF_SEMWAITQ 1
#define SSR_BERR 0x01 /* bits of system status register */
#define SSR_TICK 0x02
#define SSR_INTVL 0x04
#define SSR_BIT3 0x08
#define SSR_PWRF 0x10
#define SSR_PRNT 0x20
#define SSR_INTEN 0x40
#define SSR_INIT 0x80
/* fixed interrupts */
#define INT_BERR 0 /* interrupt levels */
#define INT_PWRF 1
#define INT_DMAFD 2
#define INT_CONR 3 /* Appendix B.0.1 has CONT and CONR swapped, see Errata */
#define INT_CONT 4
#define INT_PRNT 5
#define INT_TICK 6
#define INT_INTVL 7
/* assignable QBUS interrupts, daisy-chained - highest prio = 8, lowest = 31 */
#define INT_QBUS8 8
#define INT_QBUS9 9
#define INT_QBUS10 10
#define INT_QBUS11 11
#define INT_QBUS12 12
#define INT_QBUS13 13
#define INT_QBUS14 14
#define INT_QBUS15 15
#define INT_QBUS16 16
#define INT_QBUS17 17
#define INT_QBUS18 18
#define INT_QBUS19 19
#define INT_QBUS20 20
#define INT_QBUS21 21
#define INT_QBUS22 22
#define INT_QBUS23 23
#define INT_QBUS24 24
#define INT_QBUS25 25
#define INT_QBUS26 26
#define INT_QBUS27 27
#define INT_QBUS28 28
#define INT_QBUS29 29
#define INT_QBUS30 30
#define INT_QBUS31 31
/* common unit user-defined attributes */
#define u_unitno u3
/* Memory */
#define MEMSIZE 65536 /* memory size in bytes */
#define MAXMEMSIZE (65535 * 2) /* maximum memory size in bytes */
#define memorysize uptr->capac
/* CPU Unit flags */
#define UNIT_V_PDQ3 (UNIT_V_UF + 0)
#define UNIT_V_MSIZE (UNIT_V_UF + 1)
#define UNIT_V_PASEXC (UNIT_V_UF + 2)
#define UNIT_PDQ3 (1u << UNIT_V_PDQ3)
#define UNIT_MSIZE (1u << UNIT_V_MSIZE)
#define UNIT_PASEXC (1u << UNIT_V_PASEXC)
#define Q_PDQ3 (cpu_unit.flags & UNIT_PDQ3)
#define Q_MSIZE (cpu_unit.flags & UNIT_MSIZE)
#define Q_PASEXC (cpu_unit.flags & UNIT_PASEXC)
#define setbit(reg,val) reg |= (val)
#define clrbit(reg,val) reg &= ~(val)
#define isbitset(reg, val) (reg & (val))
#define isbitclr(reg, val) ((reg & (val)) == 0)
/* debug flags */
#define DBG_NONE 0x0000
#define DBG_FD_CMD 0x0001
#define DBG_FD_READ 0x0002
#define DBG_FD_WRITE 0x0004
#define DBG_FD_SVC 0x0008
#define DBG_FD_IMD 0x0010
#define DBG_FD_IMD2 0x0020 /* deep inspection */
#define DBG_FD_DMA 0x0040
#define DBG_FD_DMA2 0x0080 /* deep inspection */
//define DBG_CPU_TRACE 0x0001 unused
#define DBG_CPU_INT 0x0001
#define DBG_CPU_INT2 0x0002 /* deep inspection */
#define DBG_CPU_READ 0x0004
#define DBG_CPU_WRITE 0x0008
#define DBG_CPU_FETCH 0x0010
#define DBG_CPU_PUSH 0x0020
#define DBG_CPU_POP 0x0040
#define DBG_CPU_PICK 0x0080
#define DBG_CPU_STACK (DBG_CPU_PUSH|DBG_CPU_POP|DBG_CPU_PICK)
#define DBG_CPU_CONC 0x0100
#define DBG_CPU_CONC2 0x0200 /* deep inspection */
#define DBG_CPU_CONC3 0x0400 /* even deeper inspection */
#define DBG_CON_READ 0x0001
#define DBG_CON_WRITE 0x0002
#define DBG_CON_SVC 0x0004
#define DBG_TIM_READ 0x0001
#define DBG_TIM_WRITE 0x0002
#define DBG_TIM_SVC 0x0004
#define DBG_PCFORMAT0 "[%04x:%04x] "
#define DBG_PCFORMAT1 " [%04x:%04x] "
#define DBG_PCFORMAT2 " [%04x:%04x] "
#define DBG_PC reg_segb,ADDR_OFF(PCX)
#define DBG_PC2 reg_segb,reg_ipc
/* calibration timers */
#define TMR_CONPOLL 0
/* console sio data rates */
#define CON_POLLUNIT 0
#define CON_TERMUNIT 1
#define CON_POLLFIRST 1 /* immediate */
#define CON_POLLRATE 100
#define CON_POLLWAIT 12500
//#define CON_TERMRATE 1300
#define CON_TERMRATE 300
/* floppy size */
#define FDC_MAX_TRACKS 77
/* IMD anachronism */
#ifndef MAX_COMMENT_LEN
#define MAX_COMMENT_LEN 256
#endif
/* XXX @TODO Pascal error codes (Raise()) */
#define PASERROR_SYSTEM 0
#define PASERROR_VALRANGE 1
#define PASERROR_NOSEG 2
#define PASERROR_PROCERR 3
#define PASERROR_STKOVFL 4
#define PASERROR_INTOVFL 5
#define PASERROR_DIVZERO 6
#define PASERROR_MEMERR 7
#define PASERROR_USERBRK 8
#define PASERROR_SYSIO 9
#define PASERROR_USERIO 10
#define PASERROR_UNIMPL 11
#define PASERROR_FPERR 12
#define PASERROR_STRINGOVFL 13
#define PASERROR_HALT 14
/* simh error codes */
#define STOP_IBKPT 1
#define STOP_MEM 2
#define STOP_ERROP 3
#define STOP_ERRADR 4
#define STOP_ERRIO 5
#define STOP_IMPL 6
#define STOP_BPT 7
#define STOP_DBGPRE 8
#define STOP_DBGPOST 9
#define STOP_PASEXC 10
/* IO addresses and vectors */
#define CON_IOBASE 0xfc10
#define CON_RCV_VEC 0x0012
#define CON_XMT_VEC 0x000e
#define CON_PRT_VEC 0x0016
#define SES_IOBASE 0xfc18
#define SES_BERR_VEC 0x0002
#define SES_PWRF_VEC 0x0006
#define SSR_IOBASE 0xfc24
#define TIM_IOBASE 0xfc20
#define TIM_TICK_VEC 0x001a
#define TIM_INTVL_VEC 0x001e
#define FDC_IOBASE 0xfc30
#define FDC_VEC 0x000a
#define CPU_SERIALNO 0xf5ff /* is part of ROM */
#define ROM_BASE 0xfc68
#define ROM 0xf400
#define ROM_SIZE 0x01ff /* excluding serial number */
/* address calculations */
#define ADDRMASK_SEG 0xffff0000
#define ADDRMASK_OFF 0x0000ffff
#define ADDR_16bit(a) ((a) & 0x0000ffff)
#define ADDR_SEG(a) (((a)>>16) & ADDRMASK_OFF)
#define ADDR_OFF(a) ((a) & ADDRMASK_OFF)
#define MAKE_BADDR(s,o) ((ADDR_16bit(s)<<16) | ADDR_16bit(o))
#define MAKE_WADDR(a) MAKE_BADDR(NIL,ADDR_OFF(a))
#define ADDR_ISWORD(a) (ADDR_SEG(a) == NIL)
/* opcode table */
#define OP_ERROR -1
#define OP_NULL 0
#define OP_UB 1
#define OP_W 2
#define OP_B 3
#define OP_DBB 4
#define OP_UBB 5
#define OP_BUB 6
#define OP_SB 7
#define OP_DBUB 8
#define OP_UBUB 9
#define OP_UBDBUB 10
#define OP_DB 11
#define OP_SW 12
#define OP_AB 13
typedef struct _optable {
char* name;
int16 flags;
} OPTABLE;
extern OPTABLE optable[];
/* debug support */
#define DEBUG_OPDBGFILE "opcode.dbg"
#define DEBUG_MINOPCODE 0
#define DEBUG_MAXOPCODE 0xe8
#define DEBUG_VALIDOP(op) (optable[op].flags >= 0)
#define DEBUG_PRE 0x01
#define DEBUG_POST 0x02
extern t_stat dbg_init();
extern t_stat dbg_check(t_value data,uint8 prepost);
extern t_stat dbg_dump_tib(FILE* fd, uint16 base);
extern t_stat dbg_dump_queue(FILE* fd, const char* qname, uint16 q);
extern t_stat dbg_dump_mscw(FILE* fd, uint16 base);
extern t_stat dbg_dump_seg(FILE* fd, uint16 segptr);
extern t_stat dbg_dump_segtbl(FILE* fd);
extern t_stat dbg_segtrack(uint16 segbase);
extern t_stat dbg_procenter(uint16 segbase, uint16 procno, uint16 mscw, uint16 osegb);
extern t_stat dbg_procleave();
extern void dbg_enable();
extern t_stat dbg_calltree(FILE* fd);
extern t_stat dbg_enteralias(const char* key, const char* value);
extern t_stat dbg_listalias(FILE*);
/* floating point */
typedef union flcvt {
float f;
uint16 i[2];
} T_FLCVT;
/* wrapper structure for terminal multiplexer,
pointer to pointer stored in device->ctxt */
typedef struct {
int pfirst, prate; /* pollrate first time, later */
TMLN ldsc;
TMXR desc;
UNIT* term;
UNIT* poll;
} SERMUX;
extern t_stat mux_attach(UNIT*, char*, SERMUX*);
extern t_stat mux_detach(UNIT*, SERMUX*);
/* externals */
extern DEVICE cpu_dev;
extern UNIT cpu_unit;
extern DEVICE con_dev;
extern UNIT con_unit[];
extern DEVICE fdc_dev;
extern UNIT fdc_unit[];
extern DEVICE timer_dev;
extern UNIT timer_unit[];
extern t_addr PCX; /* PC at the begin of execution */
extern uint16 reg_segb;
extern uint32 reg_dmabase;
extern uint16 reg_mp;
extern uint16 reg_bp;
extern uint16 reg_sp;
extern uint16 reg_splow;
extern uint16 reg_spupr;
extern uint16 reg_ctp;
extern uint16 reg_rq;
extern uint16 reg_ipc;
extern uint16 reg_fc68;
extern uint16 reg_romsize;
extern uint16 reg_ssv;
extern uint16 reg_ssr;
extern uint16 reg_cpuserial;
extern uint32 reg_intpending;
extern t_stat Read(t_addr base, t_addr woffset, uint16 *data, uint32 dctrl);
extern t_stat Write(t_addr base, t_addr boffset, uint16 data, uint32 dctrl);
extern t_stat ReadB(t_addr base, t_addr boffset, uint16 *data, uint32 dctrl);
extern t_stat WriteB(t_addr base, t_addr boffset, uint16 data, uint32 dctrl);
extern t_stat ReadEx(t_addr base, t_addr woffset, uint16 *data);
extern t_stat ReadBEx(t_addr base, t_addr boffset, uint16 *data);
extern t_stat rom_read(t_addr base, uint16 *data);
extern t_stat rom_write(t_addr base, uint16 data);
extern t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);
extern t_stat con_read(t_addr ioaddr, uint16 *data);
extern t_stat con_write(t_addr ioaddr, uint16 data);
extern t_stat con_binit();
extern t_stat fdc_read(t_addr ioaddr, uint16 *data);
extern t_stat fdc_write(t_addr ioaddr, uint16 data);
extern t_stat fdc_autoload();
extern t_stat fdc_binit();
extern t_stat tim_read(t_addr ioaddr, uint16 *data);
extern t_stat tim_write(t_addr ioaddr, uint16 data);
extern void cpu_assertInt(int level, t_bool tf);
extern t_stat cpu_raiseInt(int level);
extern t_stat cpu_setIntVec(uint16 vector,int level);
extern void cpu_setRegs(uint16 ctp, uint16 ssv, uint16 rq);
extern void cpu_finishAutoload();
extern t_stat cpu_buserror();
typedef t_stat (*IOREAD)(t_addr ioaddr, uint16 *data);
typedef t_stat (*IOWRITE)(t_addr ioaddr, uint16 data);
typedef struct _ioinfo {
struct _ioinfo* next;
uint16 iobase;
uint16 iosize;
uint16 qvector;
uint16 qprio;
IOREAD read;
IOWRITE write;
} IOINFO;
typedef struct _devctxt {
IOINFO* ioi;
} DEVCTXT;
extern t_stat pdq3_ioinit();
extern t_stat add_ioh(IOINFO* ioi);
extern t_stat del_ioh(IOINFO* ioi);
extern t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc);
extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc);
extern t_stat set_iovec(UNIT *uptr, int32 val, char *cptr, void *desc);
extern t_stat show_iovec(FILE *st, UNIT *uptr, int value, void *desc);
extern t_stat set_ioprio(UNIT *uptr, int32 val, char *cptr, void *desc);
extern t_stat show_ioprio(FILE *st, UNIT *uptr, int value, void *desc);
#endif

1176
PDQ-3/pdq3_fdc.c Normal file

File diff suppressed because it is too large Load diff

355
PDQ-3/pdq3_mem.c Normal file
View file

@ -0,0 +1,355 @@
/*
Work derived from Copyright (c) 2004-2012, Robert M. Supnik
Copyright (c) 2013 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of Robert M Supnik and Holger Veit
shall not be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik and Holger Veit.
20130920 hv initial version, moved some code from pdq3_cpu.c
*/
#include "pdq3_defs.h"
/* the memory */
uint16 M[MAXMEMSIZE];
/******************************************************************************
* IO dispatcher
*****************************************************************************/
static t_bool initio = FALSE;
#define IOSIZE 4096
#define IOPAGEMASK 0x0fff
IOREAD ioreaders[IOSIZE];
IOWRITE iowriters[IOSIZE];
/* I/O devices are implemented this way:
* a unit will register its own I/O addresses together with its handler
* in a hash which allows simple lookup of memory mapped I/O addresses
*/
t_stat pdq3_ioinit() {
int i;
if (!initio) {
for (i=0; i < IOSIZE; i++) {
ioreaders[i] = NULL;
iowriters[i] = NULL;
}
for (i=8; i < 32; i++)
cpu_setIntVec(NIL, i);
initio = TRUE;
}
return SCPE_OK;
}
t_stat add_ioh(IOINFO* ioi) {
while (ioi) {
int i;
for (i=0; i<ioi->iosize; i++) {
int idx = (ioi->iobase + i) & IOPAGEMASK;
ioreaders[idx] = ioi->read;
iowriters[idx] = ioi->write;
}
ioi = ioi->next;
}
return SCPE_OK;
}
t_stat del_ioh(IOINFO* ioi) {
while (ioi) {
int i;
for (i=0; i<ioi->iosize; i++) {
int idx = (ioi->iobase + i) & IOPAGEMASK;
ioreaders[idx] = NULL;
iowriters[idx] = NULL;
}
ioi = ioi->next;
}
return SCPE_OK;
}
/******************************************************************************
* configuration
*****************************************************************************/
t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc) {
DEVICE* dptr;
DEVCTXT* ctxt;
IOINFO* ioi;
t_bool first = TRUE;
if (!uptr) return SCPE_IERR;
if ((dptr = find_dev_from_unit(uptr)) == 0) return SCPE_IERR;
ctxt = (DEVCTXT*)dptr->ctxt;
ioi = ctxt->ioi;
while (ioi) {
if (ioi->iobase) {
if (ioi->iobase > 0xfc00) {
fprintf(st, first ? "IOBASE=$%04x":",$%04x", ioi->iobase);
first = FALSE;
}
}
ioi = ioi->next;
}
return SCPE_OK;
}
t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc) {
t_stat rc;
DEVICE* dptr;
DEVCTXT* ctxt;
IOINFO* ioi;
t_bool first = TRUE;
if (!cptr) return SCPE_ARG;
if (!uptr) return SCPE_IERR;
if ((dptr = find_dev_from_unit(uptr)) == 0) return SCPE_IERR;
ctxt = (DEVCTXT*)dptr->ctxt;
ioi = ctxt->ioi;
if (ioi->next)
return SCPE_ARG; /* note: fixed devices on mainboard cannot be changed */
ioi->iobase = get_uint(cptr, 16, 0xffff, &rc);
return rc;
}
t_stat set_iovec(UNIT *uptr, int32 val, char *cptr, void *desc) {
t_stat rc;
DEVICE* dptr;
DEVCTXT* ctxt;
IOINFO* ioi;
t_bool first = TRUE;
if (!cptr) return SCPE_ARG;
if (!uptr) return SCPE_IERR;
if ((dptr = find_dev_from_unit(uptr)) == 0) return SCPE_IERR;
ctxt = (DEVCTXT*)dptr->ctxt;
ioi = ctxt->ioi;
if (ioi->next)
return SCPE_ARG; /* note: fixed devices on mainboard cannot be changed */
ioi->qvector = get_uint(cptr, 16, 0xff, &rc);
return rc;
}
t_stat show_iovec(FILE *st, UNIT *uptr, int value, void *desc) {
DEVICE* dptr;
DEVCTXT* ctxt;
IOINFO* ioi;
t_bool first = TRUE;
if (!uptr) return SCPE_IERR;
if ((dptr = find_dev_from_unit(uptr)) == 0) return SCPE_IERR;
ctxt = (DEVCTXT*)dptr->ctxt;
ioi = ctxt->ioi;
while (ioi) {
if (ioi->qprio < 32) {
fprintf(st, first ? "VECTOR=$%04x":",$%04x", ioi->qvector);
first = FALSE;
}
ioi = ioi->next;
}
return SCPE_OK;
}
t_stat set_ioprio(UNIT *uptr, int32 val, char *cptr, void *desc) {
t_stat rc;
DEVICE* dptr;
DEVCTXT* ctxt;
IOINFO* ioi;
t_bool first = TRUE;
if (!cptr) return SCPE_ARG;
if (!uptr) return SCPE_IERR;
if ((dptr = find_dev_from_unit(uptr)) == 0) return SCPE_IERR;
ctxt = (DEVCTXT*)dptr->ctxt;
ioi = ctxt->ioi;
if (ioi->next)
return SCPE_ARG; /* note: fixed devices on mainboard cannot be changed */
ioi->qprio = get_uint(cptr, 16, 31, &rc);
return rc;
}
t_stat show_ioprio(FILE *st, UNIT *uptr, int value, void *desc) {
DEVICE* dptr;
DEVCTXT* ctxt;
IOINFO* ioi;
t_bool first = TRUE;
if (!uptr) return SCPE_IERR;
if ((dptr = find_dev_from_unit(uptr)) == 0) return SCPE_IERR;
ctxt = (DEVCTXT*)dptr->ctxt;
ioi = ctxt->ioi;
while (ioi) {
if (ioi->qprio < 32) {
fprintf(st, first ? "PRIO=%d":",%d", ioi->qprio);
first = FALSE;
}
ioi = ioi->next;
}
return SCPE_OK;
}
/******************************************************************************
* central memory handling
*****************************************************************************/
t_stat Read(t_addr base, t_addr woffset, uint16 *data, uint32 dctrl) {
t_stat rc;
uint16 ea = base + woffset;
/* Note: the PRIAM driver attempts to read the ready bit from FF25 (bit 9) which should be 1.
* As long as we don't have a HDP device, the invalid value should be 0x0000 */
*data = 0x0000; /* preload invalid data value */
if (ea < 0xf000 || (ea == 0xfffe && cpu_unit.capac > 65535)) {
*data = M[ea]; /* normal memory */
rc = SCPE_OK;
} else {
IOREAD reader = ioreaders[ea & IOPAGEMASK];
rc = reader ? (*reader)(ea, data) : SCPE_NXM;
}
if (rc != SCPE_OK) {
cpu_buserror();
sim_debug(DBG_CPU_READ, &cpu_dev, DBG_PCFORMAT1 "Invalid Mem read from $%04x\n", DBG_PC, ea);
printf("read buserror: ea=$%04x at $%x:#%x\n",ea,reg_segb,reg_ipc);
return rc;
}
if (dctrl & DBG_CPU_PICK) {
sim_debug(DBG_CPU_PICK, &cpu_dev, DBG_PCFORMAT1 "Pick %04x at SP=$%04x\n", DBG_PC, *data, ea);
} else if (dctrl & DBG_CPU_POP) {
sim_debug(DBG_CPU_POP, &cpu_dev, DBG_PCFORMAT2 "Pop %04x from SP=$%04x\n", DBG_PC, *data, ea);
} else {
sim_debug(dctrl, &cpu_dev, DBG_PCFORMAT2 "Word read %04x from $%04x\n", DBG_PC, *data, ea);
}
return rc;
}
/* read routine that does not generate bus errors, for SIMH Examine
* will read 0x0000 for unknown memory */
t_stat ReadEx(t_addr base, t_addr woffset, uint16 *data) {
t_stat rc;
uint16 ea = base + woffset;
*data = 0x0000; /* preload invalid data value */
if (ea < 0xf000) {
*data = M[ea]; /* normal memory */
rc = SCPE_OK;
} else {
IOREAD reader = ioreaders[ea & IOPAGEMASK];
rc = reader ? (*reader)(ea, data) : SCPE_NXM;
}
return rc;
}
t_stat Write(t_addr base, t_addr woffset, uint16 data, uint32 dctrl) {
t_stat rc;
uint16 ea = base + woffset;
if (ea < 0xf000) {
M[ea] = data;
rc = SCPE_OK;
} else {
IOWRITE write = iowriters[ea & IOPAGEMASK];
rc = write ? (*write)(ea, data) : SCPE_NXM;
}
if (rc != SCPE_OK) {
cpu_buserror();
sim_debug(DBG_CPU_WRITE, &cpu_dev, DBG_PCFORMAT0 "Invalid Mem write to $%04x\n", DBG_PC, ea);
printf("write buserror %x at %x:%x\n",ea,reg_segb,reg_ipc);
//exit(1);
return rc;
}
if (dctrl & DBG_CPU_STACK)
sim_debug(DBG_CPU_PUSH, &cpu_dev, DBG_PCFORMAT1 "Push %04x to SP=$%04x\n", DBG_PC, data, ea);
else
sim_debug(dctrl, &cpu_dev, DBG_PCFORMAT2 "Word write %04x to $%04x\n", DBG_PC, data, ea);
return rc;
}
t_stat ReadB(t_addr base, t_addr boffset, uint16 *data, uint32 dctrl)
{
t_stat rc;
t_addr ea = base + boffset/2;
if ((rc=Read(ea, 0, data, DBG_NONE)) != SCPE_OK) return rc;
if (boffset & 1)
*data >>= 8;
*data &= 0xff;
if (dctrl & DBG_CPU_FETCH)
sim_debug(DBG_CPU_FETCH, &cpu_dev, DBG_PCFORMAT0 "Fetch %02x from SEGB:%04x\n",
DBG_PC, *data, reg_ipc);
else
sim_debug(dctrl, &cpu_dev, DBG_PCFORMAT2 "Byte[%d] read %02x from $%04x\n",
DBG_PC, boffset & 1, *data, ea);
return SCPE_OK;
}
t_stat ReadBEx(t_addr base, t_addr boffset, uint16 *data)
{
t_stat rc;
t_addr ea = base + boffset/2;
if ((rc=ReadEx(ea, 0, data)) != SCPE_OK) return rc;
if (boffset & 1)
*data >>= 8;
*data &= 0xff;
return SCPE_OK;
}
t_stat WriteB(t_addr base, t_addr boffset, uint16 data, uint32 dctrl)
{
uint16 wdata;
t_addr ea = base + boffset/2;
if (ea < 0xfc00) {
sim_debug(dctrl, &cpu_dev, DBG_PCFORMAT2 "Byte[%d] write %02x to $%04x\n",
DBG_PC, boffset & 1, data, ea);
wdata = M[ea];
} else {
printf(DBG_PCFORMAT0 "Invalid byte[%d] write %02x to I/O addr $%04x\n", DBG_PC, boffset & 1, data, ea);
return STOP_ERRIO;
}
if (boffset & 1) {
wdata = (wdata & 0xff) | (data<<8);
} else {
wdata = (wdata & 0xff00) | (data & 0xff);
}
return Write(ea, 0, wdata, 0);
}
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 mc;
t_addr i;
if (val < 0 || val > 1)
return SCPE_ARG;
val = val ? 65536 : 32768;
for (mc = 0, i = val; i < memorysize; i++)
mc = mc | M[i];
if (mc && !get_yn ("Really truncate memory [N]?", FALSE))
return SCPE_OK;
memorysize = val;
for (i = memorysize; i < MAXMEMSIZE; i++)
M[i] = 0;
return SCPE_OK;
}
t_stat rom_read(t_addr ea, uint16 *data)
{
*data = M[ea];
return SCPE_OK;
}
t_stat rom_write(t_addr ea, uint16 data) {
M[ea] = data;
return SCPE_OK;
}

641
PDQ-3/pdq3_stddev.c Normal file
View file

@ -0,0 +1,641 @@
/* PDQ3_stddev.c: PDQ3 simulator standard devices
Work derived from Copyright (c) 2004-2012, Robert M. Supnik
Copyright (c) 2013 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of Robert M Supnik and Holger Veit
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization from
Robert M Supnik and Holger Veit.
20130902 hv added telnet multiplexer code
20131020 hv fixed CON interrupt handling
20131103 hv connect CON_ATTACH logic with DSR, so that DSR is set if tcp connect
*/
#include "pdq3_defs.h"
#include <ctype.h>
extern UNIT cpu_unit;
extern int32 sim_switches;
extern UNIT con_unit[];
static t_stat con_termsvc(UNIT *uptr);
static t_stat con_pollsvc(UNIT *uptr);
static t_stat con_attach(UNIT*, char*);
static t_stat con_detach(UNIT*);
static t_stat con_reset(DEVICE* dptr);
static t_stat tim_reset(DEVICE *dptr);
static t_stat tim0_svc(UNIT* uptr);
static t_stat tim1_svc(UNIT* uptr);
static t_stat tim2_svc(UNIT* uptr);
/* CON USART registers */
/* This is described as positive logic, and represents the
* content of the corresponding registers.
* However, the USART is connected to inverted DAL lines
* and needs to be written to with the inverted value
* This is done in CPU Read/Write */
#define CONC1_LOOP 0x80 /* 0=loopmode diagnostic, 1=normal full duplex */
#define CONC1_BRK 0x40 /* 1=send break */
#define CONC1_MISC 0x20 /* 1=one stop bit, 0=two */
#define CONC1_ECHO 0x10 /* 1=echo received data */
#define CONC1_PE 0x08 /* 1=check parity */
#define CONC1_RE 0x04 /* 1=enable receiver */
#define CONC1_RTS 0x02 /* 1=enable transmitter if CTS */
#define CONC1_DTR 0x01 /* 1=enable CD, DSR,RI interrupts */
static uint8 con_ctrl1;
#define CONC2_CLENMASK 0xc0 /* number of bits */
#define CONC2_CLEN8 0x00
#define CONC2_CLEN7 0x40
#define CONC2_CLEN6 0x80
#define CONC2_CLEN5 0xc0
#define CONC2_MODE 0x20 /* not used set to 0 (async mode) */
#define CONC2_ODDEVN 0x10 /* 0=even parity */
#define CONC2_RXCLK 0x08 /* not used, set to 1 */
#define CONC2_CLKMASK 0x07 /* clock selector */
#define CONC2_CLK110 0x06 /* must be set to 001 (rate 1 clock) */
static uint8 con_ctrl2;
#define CONS_DSC 0x80 /* set to 1 after status read, cleared by DSR/DCD/RI */
#define CONS_DSR 0x40 /* DSR input */
#define CONS_CD 0x20 /* DCD input */
#define CONS_FE 0x10 /* 1=framing error */
#define CONS_PE 0x08 /* 1=parity error */
#define CONS_OE 0x04 /* 1= overrun error */
#define CONS_DR 0x02 /* set to 1 if data received, 0 if data read */
#define CONS_THRE 0x01 /* set to 1 if data xmit buffer empty */
static uint8 con_status;
static uint8 con_xmit;
static uint8 con_rcv;
/************************************************************************************************
* Utilities
***********************************************************************************************/
t_stat mux_attach(UNIT* uptr, char* cptr, SERMUX* mux) {
t_stat rc;
mux->desc.ldsc = &mux->ldsc;
if ((rc = tmxr_attach(&mux->desc, uptr, cptr)) == SCPE_OK) {
mux->poll->wait = mux->pfirst;
sim_activate(mux->poll, mux->poll->wait);
}
return rc;
}
t_stat mux_detach(UNIT* uptr, SERMUX* mux) {
t_stat rc = tmxr_detach(&mux->desc, uptr);
mux->ldsc.rcve = 0;
sim_cancel(mux->poll);
sim_cancel(mux->term);
return rc;
}
/************************************************************************************************
* Onboard Console
***********************************************************************************************/
/* con data structures
con_dev con device descriptor
con_unit con unit descriptor
con_mod con modifier list
con_reg con register list
*/
IOINFO con_ioinfo1 = { NULL, CON_IOBASE, 4, CON_RCV_VEC, 4, con_read, con_write };
IOINFO con_ioinfo2 = { &con_ioinfo1, 0, 0, CON_XMT_VEC, 3, con_read, con_write };
DEVCTXT con_ctxt = { &con_ioinfo2 };
UNIT con_unit[] = {
{ UDATA (&con_pollsvc, UNIT_ATTABLE, 0), CON_POLLRATE, },
{ UDATA (&con_termsvc, UNIT_IDLE, 0), CON_TERMRATE, }
};
REG con_reg[] = {
{ HRDATA (CTRL1, con_ctrl1, 8) },
{ HRDATA (CTRL2, con_ctrl2, 8) },
{ HRDATA (STAT, con_status, 8) },
{ HRDATA (XMIT, con_xmit, 8) },
{ HRDATA (RCV, con_rcv, 8) },
{ NULL }
};
MTAB con_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", NULL, &show_iobase },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", NULL, &show_iovec },
{ MTAB_XTD|MTAB_VDV, 0, "PRIO", "PRIO", NULL, &show_ioprio },
{ 0 }
};
DEBTAB con_dflags[] = {
{ "WRITE", DBG_CON_WRITE },
{ "READ", DBG_CON_READ },
{ "SVC", DBG_CON_SVC },
{ 0, 0 }
};
SERMUX con_mux[1] = {
{ CON_POLLFIRST, /*pfirst*/
CON_POLLRATE, /*prate*/
{ 0 }, /*ldsc*/
{ 1,0,0,0 }, /*desc*/
&con_unit[1], /*term*/
&con_unit[0] /*poll*/
}
};
DEVICE con_dev = {
"CON", /*name*/
con_unit, /*units*/
con_reg, /*registers*/
con_mod, /*modifiers*/
2, /*numunits*/
16, /*aradix*/
16, /*awidth*/
1, /*aincr*/
8, /*dradix*/
8, /*dwidth*/
NULL, /*examine*/
NULL, /*deposit*/
&con_reset, /*reset*/
NULL, /*boot*/
con_attach, /*attach*/
con_detach, /*detach*/
&con_ctxt, /*ctxt*/
DEV_DEBUG|DEV_DISABLE, /*flags*/
0, /*dctrl*/
con_dflags, /*debflags*/
NULL, /*msize*/
NULL /*lname*/
};
/* bus reset handler */
t_stat con_binit() {
SERMUX *mux = &con_mux[0];
con_status = CONS_THRE;
if (mux->ldsc.conn) setbit(con_status, CONS_DSR);
con_ctrl1 = 0; /* no echo, receiver disabled, transmitter disabled */
con_ctrl2 = 0; /* ASYNC mode, 8bits, Clock 1X */
con_xmit = 0;
con_rcv = 0;
return SCPE_OK;
}
/* common handlers */
static t_stat con_reset(DEVICE* dptr)
{
int32 wait;
SERMUX * mux = &con_mux[0];
UNIT *term = mux->term;
UNIT *poll = mux->poll;
DEVCTXT* ctxt = (DEVCTXT*)dptr->ctxt;
wait = poll->wait = CON_POLLWAIT;
sim_rtcn_init (wait, TMR_CONPOLL); /* init poll timer */
sim_cancel(term);
/* register/deregister I/O handlers */
if (dptr->flags & DEV_DIS) {
del_ioh(ctxt->ioi);
} else {
add_ioh(ctxt->ioi);
poll->buf = 0;
sim_activate (poll, wait);
}
return con_binit();
}
t_stat con_attach(UNIT* uptr, char* cptr) {
setbit(con_status, CONS_DSR|CONS_DSC);
return mux_attach(uptr, cptr, &con_mux[0]);
}
t_stat con_detach(UNIT* uptr) {
clrbit(con_status, CONS_DSR);
setbit(con_status, CONS_DSC);
return mux_detach(uptr, &con_mux[0]);
}
#define XMITENABLED() (isbitset(con_ctrl1,CONC1_RTS))
#define XMITENABLE() setbit(con_ctrl1,CONC1_RTS)
#define XMITDISABLE() clrbit(con_ctrl1,CONC1_RTS)
#define XMITEMPTY() (isbitset(con_status, CONS_THRE))
#define RCVENABLED() (isbitset(con_ctrl1,CONC1_RE))
#define RCVFULL() (isbitset(con_status, CONS_DR))
#define RCVENABLE() setbit(con_ctrl1,CONC1_RE)
#define RCVDISABLE() clrbit(con_ctrl1,CONC1_RE)
#define DSRACTIVE() (isbitset(con_ctrl1,CONC1_DTR) && isbitset(con_status,CONS_DSR))
/* The transmit interrupt is raised continuously,
* as long as the transmit holding reg is empty and the transmitter is enabled.
* It will be deasserted when the tranmit reg is full or tranmitter disabled.
*/
#define XMITINTR() cpu_assertInt(INT_CONT, XMITEMPTY())
/* The receive interrupt is raised continuously,
* when the receiver holding register is full and the receiver is enabled.
* it will be deasserted when the receiver reg is read or the receiver disabled.
*/
#define RCVINTR() cpu_assertInt(INT_CONR, RCVFULL())
/* The DSR interrupt is raised when DSC is set to 1 (pos logic)
* and DTR is active, cleared if status is read */
#define DSRINTR() cpu_assertInt(INT_PRNT, DSRACTIVE())
/* Terminal output service */
t_stat con_termsvc (UNIT *uptr) {
SERMUX *mux = &con_mux[0];
t_bool isnetwork = (mux->poll->flags & UNIT_ATT);
t_stat rc;
int ch = uptr->buf & 0xff;
// sim_debug(DBG_CON_SVC, &con_dev, "termsvc: isnetwork=%d\n",isnetwork);
/* TODO? sim_tt_outcvt */
if (XMITENABLED()) { /* tranmitter enabled */
/* attached to a telnet port? */
// printf("*** Emit: %02x ***\n",uptr->buf & 0xff);
if (isnetwork) {
if ((rc=tmxr_putc_ln(&mux->ldsc, ch)) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
return SCPE_OK;
} else
tmxr_poll_tx(&mux->desc);
} else {
if ((rc=sim_putchar_s(ch)) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
return rc==SCPE_STALL ? SCPE_OK : rc;
}
}
setbit(con_status,CONS_THRE); /* set transmitter holding reg empty */
cpu_assertInt(INT_CONT, TRUE); /* generate an interrupt because of DRQO */
}
return SCPE_OK;
}
/* Terminal input service */
t_stat con_pollsvc(UNIT *uptr) {
int32 c, kbdc;
SERMUX *mux = &con_mux[0];
t_bool isnetwork = (mux->poll->flags & UNIT_ATT);
uptr->wait = sim_rtcn_calb(mux->prate, TMR_CONPOLL); /* calibrate timer */
sim_activate (uptr, uptr->wait); /* restart polling */
kbdc = sim_poll_kbd(); /* check keyboard */
if (kbdc == SCPE_STOP) return kbdc; /* handle CTRL-E */
/* network-redirected input? */
if (isnetwork) {
if (tmxr_poll_conn(&mux->desc) >= 0) /* incoming connection */
mux->ldsc.rcve = 1;
tmxr_poll_rx(&mux->desc); /* poll for input */
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
/* input ready */
c = tmxr_getc_ln(&mux->ldsc);
if ((c & TMXR_VALID) == 0) return SCPE_OK;
} else {
c = kbdc; /* use char polled from keyboard */
if (c < SCPE_KFLAG) return c; /* ignore data if not valid */
}
c = sim_tt_inpcvt(c, TT_GET_MODE(uptr->flags));
uptr->buf = c & 0xff;
uptr->pos = uptr->pos + 1;
if (RCVENABLED()) { /* receiver enabled? */
if (RCVFULL()) /* handle data overrun */
setbit(con_status,CONS_OE);
con_rcv = c & 0xff; /* put in receiver register */
setbit(con_status,CONS_DR); /* notify: data received */
cpu_assertInt(INT_CONR, TRUE); /* generate interrupt because of DRQI */
if (isbitset(con_ctrl1, CONC1_ECHO)) { /* echo? XXX handle in telnet handler? */
/* XXX use direct send here, not sending via con_termsvc */
if (isnetwork)
tmxr_putc_ln(&mux->ldsc, c);
else
sim_putchar_s(c);
}
}
return SCPE_OK;
}
static int set_parity(int c, int odd)
{
int i, p = 0;
for (i=0; i<8; i++)
if (c & (1<<i)) p ^= 1;
c |= p ? 0 : 0x80;
if (!odd) c ^= 0x80;
return c;
}
static int get_parity(int c, int even)
{
int i, p = 0;
for (i=0; i<8; i++)
if (c & (1<<i)) p ^= 1;
if (even) p ^= 1;
return p;
}
// functions from memory handler to read and write a char
// note: the usart is connected to inverted data lines,
// this is fixed by negating input and output
//
// The logic in here uses the positive logic conventions as
// described in the WD1931 data sheet, not the ones in the PDQ-3_Hardware_Users_Manual
t_stat con_write(t_addr ioaddr, uint16 data) {
SERMUX * mux = &con_mux[0];
UNIT *term = mux->term;
UNIT *poll = mux->poll;
/* note usart has inverted bus, so all data is inverted */
data = (~data) & 0xff;
switch (ioaddr & 0x0003) {
case 0: /* CTRL1 */
con_ctrl1 = data;
if (!RCVENABLED()) { /* disable receiver */
clrbit(con_status,CONS_FE|CONS_PE|CONS_OE|CONS_DR);
sim_cancel(poll);
} else {
sim_activate(poll, poll->wait); /* start poll service, will raise interrupt if buffer full */
}
if (!XMITENABLED()) { /* disable transmitter */
/* will drain current pending xmit service. RTS output is assumed to become inactive
* (it is not necessary to emulate it) */
} else {
if (XMITEMPTY()) {
} else {
/* some char in THR, start service to emit */
sim_activate(term, term->wait);
}
}
break;
case 1:
con_ctrl2 = data;
break;
case 2:
// ignore this here - DLE register
break;
case 3:
switch (con_ctrl2 & CONC2_CLENMASK) {
case CONC2_CLEN5: data &= 0x1f; break;
case CONC2_CLEN6: data &= 0x3f; break;
case CONC2_CLEN7: data &= 0x7f;
if (isbitset(con_ctrl1,CONC1_PE))
data = set_parity(data, con_ctrl2 & CONC2_ODDEVN);
break;
case CONC2_CLEN8: data &= 0xff; break;
}
con_xmit = data;
term->buf = data;
clrbit(con_status,CONS_THRE);
if (XMITENABLED())
sim_activate(term,term->wait);
}
// RCVINTR();
XMITINTR();
DSRINTR();
sim_debug(DBG_CON_WRITE, &con_dev, DBG_PCFORMAT0 "Byte write %02x (pos logic) to $%04x\n", DBG_PC, data & 0xff, ioaddr);
return SCPE_OK;
}
t_stat con_read(t_addr ioaddr, uint16 *data) {
SERMUX *mux = &con_mux[0];
switch (ioaddr & 0x0003) {
case 0: /* CTRL1 */
*data = con_ctrl1;
break;
case 1:
*data = con_ctrl2;
break;
case 2:
if (mux->ldsc.conn) setbit(con_status, CONS_DSR);
else clrbit(con_status, CONS_DSR);
*data = con_status;
clrbit(con_status,CONS_DSC); /* acknowledge change in DSR/DCD */
break;
case 3:
*data = con_rcv;
clrbit(con_status,CONS_DR);
cpu_assertInt(INT_CONR, FALSE);
}
sim_debug(DBG_CON_READ, &con_dev, DBG_PCFORMAT1 "Byte read %02x (pos logic) from $%04x\n", DBG_PC, *data & 0xff, ioaddr);
/* note usart has inverted bus, so returned data must be negated */
*data = ~(*data);
return SCPE_OK;
}
/************************************************************************************************
* Onboard 8253 timer
***********************************************************************************************/
struct i8253 {
uint16 cnt;
uint16 preset;
uint16 mode;
t_bool hilo; /* which half of 16 bit cnt is to be set */
};
struct i8253 tim[3];
IOINFO tim_ioinfo1 = { NULL, TIM_IOBASE, 4, TIM_TICK_VEC, 6, tim_read, tim_write };
IOINFO tim_ioinfo2 = { &tim_ioinfo1, 0, 0, TIM_INTVL_VEC, 7, tim_read, tim_write };
DEVCTXT tim_ctxt = { &tim_ioinfo2 };
UNIT tim_unit[] = {
{ UDATA (&tim0_svc, 0, 0), CON_POLLRATE, },
{ UDATA (&tim1_svc, 0, 0), CON_POLLRATE, },
{ UDATA (&tim2_svc, 0, 0), CON_POLLRATE, }
};
REG tim_reg[] = {
{ HRDATA (CNT0, tim[0].cnt, 16) },
{ HRDATA (CNT1, tim[1].cnt, 16) },
{ HRDATA (CNT2, tim[2].cnt, 16) },
{ HRDATA (MODE0, tim[0].mode, 8) },
{ HRDATA (MODE1, tim[1].mode, 8) },
{ HRDATA (MODE2, tim[2].mode, 8) },
{ NULL }
};
MTAB tim_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE", NULL, &show_iobase },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", NULL, &show_iovec },
{ MTAB_XTD|MTAB_VDV, 0, "PRIO", "PRIO", NULL, &show_ioprio },
{ 0 }
};
DEBTAB tim_dflags[] = {
{ "WRITE", DBG_TIM_WRITE },
{ "READ", DBG_TIM_READ },
{ "SVC", DBG_TIM_SVC },
{ 0, 0 }
};
DEVICE tim_dev = {
"TIM", /*name*/
tim_unit, /*units*/
tim_reg, /*registers*/
tim_mod, /*modifiers*/
3, /*numunits*/
16, /*aradix*/
16, /*awidth*/
1, /*aincr*/
8, /*dradix*/
8, /*dwidth*/
NULL, /*examine*/
NULL, /*deposit*/
&tim_reset, /*reset*/
NULL, /*boot*/
NULL, /*attach*/
NULL, /*detach*/
&tim_ctxt, /*ctxt*/
DEV_DEBUG, /*flags*/
0, /*dctrl*/
tim_dflags, /*debflags*/
NULL, /*msize*/
NULL /*lname*/
};
t_stat tim_reset(DEVICE *dptr)
{
DEVCTXT* ctxt = (DEVCTXT*)dptr->ctxt;
if (dptr->flags & DEV_DIS) {
del_ioh(ctxt->ioi);
sim_cancel(&tim_unit[0]);
sim_cancel(&tim_unit[1]);
sim_cancel(&tim_unit[2]);
} else {
add_ioh(ctxt->ioi);
}
return SCPE_OK;
}
t_stat tim_read(t_addr ioaddr, uint16 *data)
{
int n = ioaddr & 0x0003;
if (n == 3)
*data = 0xff;
else {
*data = (tim[n].hilo ? tim[n].cnt : (tim[n].cnt >> 8)) & 0xff;
sim_debug(DBG_TIM_READ, &tim_dev, DBG_PCFORMAT1 "Read %s timer%d: %02x\n",
DBG_PC, tim[n].hilo ? "high" : "low", n, *data);
tim[n].hilo = ! tim[n].hilo;
}
return SCPE_OK;
}
static uint16 sethi(uint16 val, uint16 data) {
val &= 0xff;
val |= (data << 8);
return val;
}
static uint16 setlo(uint16 val, uint16 data) {
val &= 0xff00;
val |= data;
return val;
}
t_stat tim_write(t_addr ioaddr, uint16 data)
{
int n = ioaddr & 0x0003;
data &= 0xff;
if (n == 3) {
n = (data & 0xc0) >> 6;
sim_debug(DBG_TIM_WRITE, &tim_dev, DBG_PCFORMAT0 "Timer%d: mode=%d\n",
DBG_PC, n, (data >> 1) & 7);
if (n == 3) {
printf("Unimplemented: Mode=0xc0\n");
return STOP_IMPL;
}
if (data & 0x01) {
printf("Unimplemented: BCD mode: timer=%d\n",n);
return STOP_IMPL;
}
if (!( (data & 0x0e)==0x00 || (data & 0x0e)==0x04)) {
printf("Unimplemented: Mode not 0 or 2: timer=%d\n",n);
return STOP_IMPL;
}
if ((data & 0x30) != 0x30) {
printf("Unimplemented: not 16 bit load: timer=%d\n",n);
return STOP_IMPL;
}
tim[n].mode = data;
} else {
if (tim[n].hilo) {
tim[n].preset = sethi(tim[n].preset, data);
tim[n].cnt = sethi(tim[n].cnt, data);
if (n < 2) { /* timer 2 is triggered by timer 1 */
int32 time = 1250000 / tim[n].cnt;
sim_cancel(&tim_unit[n]);
sim_activate(&tim_unit[n], time);
}
} else {
tim[n].preset = setlo(tim[n].preset, data);
tim[n].cnt = setlo(tim[n].cnt, data);
}
sim_debug(DBG_TIM_WRITE, &tim_dev, DBG_PCFORMAT0 "Timer%d: %s cnt=%02x\n",
DBG_PC, n, tim[n].hilo ? "high":"low", data);
tim[n].hilo = !tim[n].hilo;
}
return SCPE_OK;
}
/* baud rate timer 0 is programmed in mode 2 - actually, this is ignored */
static t_stat tim0_svc(UNIT* uptr)
{
int32 time = 1250000 / tim[0].preset;
sim_activate(uptr, time);
sim_debug(DBG_TIM_SVC, &tim_dev, DBG_PCFORMAT2 "Timer0: SVC call\n", DBG_PC);
return SCPE_OK;
}
/* system timer 1 is programmed in mode 2, causes interrupt each time it is 0 */
static t_stat tim1_svc(UNIT* uptr)
{
int32 time = 1250000 / tim[0].preset;
sim_debug(DBG_TIM_SVC, &tim_dev, DBG_PCFORMAT2 "Timer1: SVC call\n", DBG_PC);
sim_activate(uptr, time);
cpu_raiseInt(INT_TICK);
reg_ssr |= SSR_TICK; /* notify TICK timer int occurred */
/* handle interval timer */
if (tim[2].cnt > 0) tim[2].cnt--;
if (tim[2].cnt == 0) {
cpu_raiseInt(INT_INTVL);
reg_ssr |= SSR_INTVL; /* notify INTVL timer int occurred */
if ((tim[2].mode & 0x0e) == 0x04) {
tim[2].cnt = tim[2].preset; /* restart timer */
} /* otherwise single shot */
}
return SCPE_OK;
}
/* interval timer 2 is programmed in mode 0 (single shot) or 2 (rate generator)
* this is triggered by timer1 - svc is ignored here */
static t_stat tim2_svc(UNIT* uptr)
{
sim_debug(DBG_TIM_SVC, &tim_dev, DBG_PCFORMAT2 "Timer2: SVC call - should not occur\n", DBG_PC);
return SCPE_OK;
}

621
PDQ-3/pdq3_sys.c Normal file
View file

@ -0,0 +1,621 @@
/* pdq3_sys.c: PDQ3 simulator interface
Work derived from Copyright (c) 2004-2012, Robert M. Supnik
Copyright (c) 2013 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of Robert M Supnik and Holger Veit
shall not be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik and Holger Veit.
2013xxxx hv initial version (written up to the leval to test against bootloader)
20130907 hv added VIEWSEG command
20130925 hv added CALL and NAME command
20130927 hv wrong disassembly of LDC instr
*/
#include "pdq3_defs.h"
#include <ctype.h>
static int disass(t_addr addr);
t_stat parse_sym_m (char *cptr, t_value *val, int32 sw);
void pdq3_vm_init (void);
static t_stat pdq3_cmd_exstack(int32 arg, char *buf);
static t_stat pdq3_cmd_exmscw(int32 arg, char *buf);
static t_stat pdq3_cmd_extib(int32 arg, char *buf);
static t_stat pdq3_cmd_exseg(int32 arg, char *buf);
static t_stat pdq3_cmd_calcea(int32 arg, char *buf);
static t_stat pdq3_cmd_calltree(int32 arg, char *buf);
static t_stat pdq3_cmd_namealias(int32 arg, char *buf);
extern DEVICE cpu_dev;
extern UNIT cpu_unit;
extern DEVICE tty_dev;
extern DEVICE fdc_dev;
extern DEVICE tim_dev;
extern REG cpu_reg[];
extern uint16 M[];
extern uint16 reg_pc;
/* SCP data structures and interface routines
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax maximum number of words for examine/deposit
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "PDQ3";
REG *sim_PC = &cpu_reg[0]; /* note this is the artifical register PCX */
int32 sim_emax = 6;
DEVICE *sim_devices[] = {
&cpu_dev,
&con_dev,
&fdc_dev,
&tim_dev,
NULL
};
const char *sim_stop_messages[] = {
"---",
"PC Breakpoint",
"MEM Breakpoint",
"Invalid Opcode",
"Invalid MEM Access",
"Invalid I/O Access",
"Not yet implemented",
"BPT instruction",
"DEBUG PRE exec stop",
"DEBUG POST exec stop",
"HALT on Pascal Exception",
};
CTAB pdq3_cmds[] = {
{ "VSTACK", &pdq3_cmd_exstack, 0, "Display last N elements of stack. Top is where SP points to" },
{ "VMSCW", &pdq3_cmd_exmscw, 0, "Display current MSCW" },
{ "VTIB", &pdq3_cmd_extib, 0, "Display current TIB" },
{ "VSEG", &pdq3_cmd_exseg, 0, "Display a segment table entry" },
{ "VCALL", &pdq3_cmd_calltree, 0, "Display the call tree" },
{ "NAME", &pdq3_cmd_namealias, 0, "Define a name" },
{ NULL, NULL, 0, NULL }
};
void (*sim_vm_init)(void) = &pdq3_vm_init;
/* Loader proper */
t_stat sim_load (FILE *fi, char *cptr, char *fnam, int flag)
{
int rombase;
int c1, c2, i;
if (flag == 1) /* don't dump */
return SCPE_ARG;
/* this assumes a HDT style ROM, where the first 2 bytes refer to the
* actual word start of the ROM, e.g. with PDQ-3 the HDT ROM has 0xf401
* as the first word, so it will load at word address 0xf400, and 0xfc68
* will be preset to 0xf401
*/
c1 = fgetc(fi);
c2 = fgetc(fi);
rombase = c1 + c2 * 256;
rom_write(rombase & 0xfffe, rombase);
reg_fc68 = rombase;
i = 0;
while (!feof(fi) && i<0x1ff) {
c1 = fgetc(fi);
c2 = fgetc(fi);
rom_write(rombase+i, (uint16)(c1 + c2*256));
i++;
}
reg_romsize = i;
/* preset the cpu_serial number from ROM, may be overwritten manually for special purposes */
rom_read(rombase+i-1, &reg_cpuserial);
return SCPE_OK;
}
/* Note: this simh handles ABSOLUTE word addresses and segmented byte addresses.
* A word address addresses a single cell in memory (up to 65536 cells).
* A byte address only occurs in IPC context, it is relative to the content of
* the reg_segb register.
* Convention:
* $xxxx = word address
* xxxx:yyyy = byte address yyyy relative to segment xxxx
* #yyyy = byte address relative to current reg_segb
* The t_addr type must be 32 bit, the upper half contains the segment, the lower
* half contains the offset. If the upper half is NIL, it is a word address
*/
void pdq3_fprint_addr (FILE *st, DEVICE *dptr, t_addr addr)
{
if (ADDR_ISWORD(addr))
fprintf(st,"$");
else if (ADDR_SEG(addr) == reg_segb)
fprintf(st,"#");
else {
fprint_val (st, ADDR_SEG(addr), dptr->dradix, dptr->dwidth, PV_LEFT);
fprintf(st,":");
}
fprint_val (st, ADDR_OFF(addr), dptr->dradix, dptr->dwidth, PV_LEFT);
return;
}
t_addr pdq3_parse_addr (DEVICE *dptr, char *cptr, char **tptr)
{
t_addr seg, off;
if (cptr[0] == '#') {
off = strtotv(cptr+1, tptr, dptr->aradix);
return MAKE_BADDR(reg_segb,off);
} else if (cptr[0] == '$') {
off = strtotv(cptr+1, tptr, dptr->aradix);
return MAKE_WADDR(off);
} else {
char gbuf[CBUFSIZE];
get_glyph (cptr, gbuf, 0);
if (!strncmp(gbuf,"SEGB",4)) {
seg = reg_segb; *tptr = cptr+4;
} else
seg = strtotv(cptr, tptr, dptr->aradix);
if (*tptr[0] == ':') {
cptr = *tptr + 1;
off = strtotv(cptr, tptr, dptr->aradix);
return MAKE_BADDR(seg,off);
} else
return MAKE_WADDR(seg);
}
}
void pdq3_vm_init (void)
{
sim_vm_fprint_addr = &pdq3_fprint_addr;
sim_vm_parse_addr = &pdq3_parse_addr;
sim_vm_cmd = pdq3_cmds;
return;
}
static t_stat pdq3_cmd_exstack(int32 arg, char *buf)
{
t_stat rc;
uint16 data;
int i;
int n = buf[0] ? atol(buf) : 0;
if (n < 0) n = 0;
printf("SP: $%04x LOW: $%04x UPR: $%04x\n",
reg_sp, reg_splow, reg_spupr);
for (i=n; i>=0; i--) {
if ((rc=Read(reg_sp+i, 0, &data, 0)) != SCPE_OK) continue;
if (i==0) printf(" TOS: "); else printf(" %3d: ",i);
printf("%04x ($%04x)\n", data, reg_sp+i);
}
return SCPE_OK;
}
static t_stat pdq3_cmd_exmscw(int32 arg, char *buf)
{
char* next;
return dbg_dump_mscw(stdout, buf[0] ? pdq3_parse_addr(&cpu_dev, buf, &next) : reg_mp);
}
static t_stat pdq3_cmd_extib(int32 arg, char *buf)
{
char* next;
return dbg_dump_tib(stdout, buf[0] ? pdq3_parse_addr(&cpu_dev, buf, &next) : reg_ctp);
}
static t_stat pdq3_cmd_exseg(int32 arg, char *buf)
{
t_stat rc;
uint16 nsegs;
uint16 segnum, segptr;
char* next;
FILE* fd = stdout; /* XXX */
if (reg_ssv < 0x2030 || reg_ssv > 0xf000) {
fprintf(fd, "Cannot list segments in bootloader: incomplete tables\n");
return SCPE_NXM;
}
if ((rc=Read(reg_ssv, -1, &nsegs, 0)) != SCPE_OK) return rc;
if (buf[0]) {
segnum = pdq3_parse_addr(&cpu_dev, buf, &next);
fprintf(fd, "Segment $%02x\n", segnum);
if (segnum > nsegs) {
fprintf(fd, "Too high: maxsegs=$%02x\n",nsegs);
return SCPE_ARG;
}
if ((rc=Read(reg_ssv, segnum, &segptr, 0)) != SCPE_OK) return rc;
rc = dbg_dump_seg(fd, segptr);
} else
rc = dbg_dump_segtbl(fd);
return rc;
}
static t_stat pdq3_cmd_calltree(int32 arg, char *buf) {
return dbg_calltree(stdout);
}
static t_stat pdq3_cmd_namealias(int32 arg, char *buf) {
char* name, *alias;
if (buf[0]==0)
return dbg_listalias(stdout);
name = strtok(buf, " \t");
alias = strtok(NULL, " \t\n");
return dbg_enteralias(name,alias);
}
/**************************************************************************************
* PDQ utility functions
*************************************************************************************/
OPTABLE optable[] = {
/*00*/ { "SLDC0", OP_NULL }, { "SLDC1", OP_NULL },
/*02*/ { "SLDC2", OP_NULL }, { "SLDC3", OP_NULL },
/*04*/ { "SLDC4", OP_NULL }, { "SLDC5", OP_NULL },
/*06*/ { "SLDC6", OP_NULL }, { "SLDC7", OP_NULL },
/*08*/ { "SLDC8", OP_NULL }, { "SLDC9", OP_NULL },
/*0a*/ { "SLDC10", OP_NULL }, { "SLDC11", OP_NULL },
/*0c*/ { "SLDC12", OP_NULL }, { "SLDC13", OP_NULL },
/*0e*/ { "SLDC14", OP_NULL }, { "SLDC15", OP_NULL },
/*10*/ { "SLDC16", OP_NULL }, { "SLDC17", OP_NULL },
/*12*/ { "SLDC18", OP_NULL }, { "SLDC19", OP_NULL },
/*14*/ { "SLDC20", OP_NULL }, { "SLDC21", OP_NULL },
/*16*/ { "SLDC22", OP_NULL }, { "SLDC23", OP_NULL },
/*18*/ { "SLDC24", OP_NULL }, { "SLDC25", OP_NULL },
/*1a*/ { "SLDC26", OP_NULL }, { "SLDC27", OP_NULL },
/*1c*/ { "SLDC28", OP_NULL }, { "SLDC29", OP_NULL },
/*1e*/ { "SLDC30", OP_NULL }, { "SLDC31", OP_NULL },
/*20*/ { "SLDL1", OP_NULL }, { "SLDL2", OP_NULL },
/*22*/ { "SLDL3", OP_NULL }, { "SLDL4", OP_NULL },
/*24*/ { "SLDL5", OP_NULL }, { "SLDL6", OP_NULL },
/*26*/ { "SLDL7", OP_NULL }, { "SLDL8", OP_NULL },
/*28*/ { "SLDL9", OP_NULL }, { "SLDL10", OP_NULL },
/*2a*/ { "SLDL11", OP_NULL }, { "SLDL12", OP_NULL },
/*2c*/ { "SLDL13", OP_NULL }, { "SLDL14", OP_NULL },
/*2e*/ { "SLDL15", OP_NULL }, { "SLDL16", OP_NULL },
/*30*/ { "SLDO1", OP_NULL }, { "SLDO2", OP_NULL },
/*32*/ { "SLDO3", OP_NULL }, { "SLDO4", OP_NULL },
/*34*/ { "SLDO5", OP_NULL }, { "SLDO6", OP_NULL },
/*36*/ { "SLDO7", OP_NULL }, { "SLDO8", OP_NULL },
/*38*/ { "SLDO9", OP_NULL }, { "SLDO10", OP_NULL },
/*3a*/ { "SLDO11", OP_NULL }, { "SLDO12", OP_NULL },
/*3c*/ { "SLDO13", OP_NULL }, { "SLDO14", OP_NULL },
/*3e*/ { "SLDO15", OP_NULL }, { "SLDO16", OP_NULL },
/*40*/ { "", OP_ERROR }, { "", OP_ERROR },
/*42*/ { "", OP_ERROR }, { "", OP_ERROR },
/*44*/ { "", OP_ERROR }, { "", OP_ERROR },
/*46*/ { "", OP_ERROR }, { "", OP_ERROR },
/*48*/ { "", OP_ERROR }, { "", OP_ERROR },
/*4a*/ { "", OP_ERROR }, { "", OP_ERROR },
/*4c*/ { "", OP_ERROR }, { "", OP_ERROR },
/*4e*/ { "", OP_ERROR }, { "", OP_ERROR },
/*50*/ { "", OP_ERROR }, { "", OP_ERROR },
/*52*/ { "", OP_ERROR }, { "", OP_ERROR },
/*54*/ { "", OP_ERROR }, { "", OP_ERROR },
/*56*/ { "", OP_ERROR }, { "", OP_ERROR },
/*58*/ { "", OP_ERROR }, { "", OP_ERROR },
/*5a*/ { "", OP_ERROR }, { "", OP_ERROR },
/*5c*/ { "", OP_ERROR }, { "", OP_ERROR },
/*5e*/ { "", OP_ERROR }, { "", OP_ERROR },
/*60*/ { "", OP_ERROR }, { "", OP_ERROR },
/*62*/ { "", OP_ERROR }, { "", OP_ERROR },
/*64*/ { "", OP_ERROR }, { "", OP_ERROR },
/*66*/ { "", OP_ERROR }, { "", OP_ERROR },
/*68*/ { "", OP_ERROR }, { "", OP_ERROR },
/*6a*/ { "", OP_ERROR }, { "", OP_ERROR },
/*6c*/ { "", OP_ERROR }, { "", OP_ERROR },
/*6e*/ { "", OP_ERROR }, { "", OP_ERROR },
/*70*/ { "", OP_ERROR }, { "", OP_ERROR },
/*72*/ { "", OP_ERROR }, { "", OP_ERROR },
/*74*/ { "", OP_ERROR }, { "", OP_ERROR },
/*76*/ { "", OP_ERROR }, { "", OP_ERROR },
/*78*/ { "SIND0", OP_NULL }, { "SIND1", OP_NULL },
/*7a*/ { "SIND2", OP_NULL }, { "SIND3", OP_NULL },
/*7c*/ { "SIND4", OP_NULL }, { "SIND5", OP_NULL },
/*7e*/ { "SIND6", OP_NULL }, { "SIND7", OP_NULL },
/*80*/ { "LDCB", OP_UB }, { "LDCI", OP_W },
/*82*/ { "LCA", OP_AB }, { "LDC", OP_BUB },
/*84*/ { "LLA", OP_B }, { "LDO", OP_B },
/*86*/ { "LAO", OP_B }, { "LDL", OP_B },
/*88*/ { "LDA", OP_DBB }, { "LOD", OP_DBB },
/*8a*/ { "UJP", OP_SB }, { "UJPL", OP_SW },
/*8c*/ { "MPI", OP_NULL }, { "DVI", OP_NULL },
/*8e*/ { "STM", OP_UB }, { "MODI", OP_NULL },
/*90*/ { "CPL", OP_UB }, { "CPG", OP_UB },
/*92*/ { "CPI", OP_DBUB }, { "CXL", OP_UBUB },
/*94*/ { "CXG", OP_UBUB }, { "CXI", OP_UBDBUB },
/*96*/ { "RPU", OP_B }, { "CPF", OP_NULL },
/*98*/ { "LDCN", OP_NULL }, { "LSL", OP_DB },
/*9a*/ { "LDE", OP_UBB }, { "LAE", OP_UBB },
/*9c*/ { "NOP", OP_NULL }, { "LPR", OP_NULL },
/*9e*/ { "BPT", OP_NULL }, { "BNOT", OP_NULL },
/*a0*/ { "LOR", OP_NULL }, { "LAND", OP_NULL },
/*a2*/ { "ADI", OP_NULL }, { "SBI", OP_NULL },
/*a4*/ { "STL", OP_B }, { "SRO", OP_B },
/*a6*/ { "STR", OP_DBB }, { "LDB", OP_NULL },
/*a8*/ { "LHO", OP_NULL }, { "LVO", OP_NULL },
/*aa*/ { "", OP_ERROR }, { "", OP_ERROR },
/*ac*/ { "", OP_ERROR }, { "", OP_ERROR },
/*ae*/ { "", OP_ERROR }, { "", OP_ERROR },
/*b0*/ { "EQUI", OP_NULL }, { "NEQI", OP_NULL },
/*b2*/ { "LEQI", OP_NULL }, { "GEQI", OP_NULL },
/*b4*/ { "LEUSW", OP_NULL }, { "GEUSW", OP_NULL },
/*b6*/ { "EQUPWR", OP_NULL }, { "LEQPWR", OP_NULL },
/*b8*/ { "GEQPWR", OP_NULL }, { "EQUBYT", OP_B },
/*ba*/ { "LEQBYT", OP_B }, { "GEQBYT", OP_B },
/*bc*/ { "SRS", OP_NULL }, { "SWAP", OP_NULL },
/*be*/ { "TNC", OP_NULL }, { "RND", OP_NULL },
/*c0*/ { "ADR", OP_NULL }, { "SBR", OP_NULL },
/*c2*/ { "MPR", OP_NULL }, { "DVR", OP_NULL },
/*c4*/ { "STO", OP_NULL }, { "MOV", OP_B },
/*c6*/ { "DUP2", OP_NULL }, { "ADJ", OP_UB },
/*c8*/ { "STB", OP_NULL }, { "LDP", OP_NULL },
/*ca*/ { "STP", OP_NULL }, { "CHK", OP_NULL },
/*cc*/ { "FLT", OP_NULL }, { "EQUREAL",OP_NULL },
/*ce*/ { "LEQREAL",OP_NULL }, { "GEQREAL",OP_NULL },
/*d0*/ { "LDM", OP_UB }, { "SPR", OP_NULL },
/*d2*/ { "EFJ", OP_SB }, { "NFJ", OP_SB },
/*d4*/ { "FJP", OP_SB }, { "FJPL", OP_SW },
/*d6*/ { "XJP", OP_B }, { "IXA", OP_B },
/*d8*/ { "IXP", OP_UBUB }, { "STE", OP_UBB },
/*da*/ { "INN", OP_NULL }, { "UNI", OP_NULL },
/*dc*/ { "INT", OP_NULL }, { "DIF", OP_NULL },
/*de*/ { "SIGNAL", OP_NULL }, { "WAIT", OP_NULL },
/*e0*/ { "ABI", OP_NULL }, { "NGI", OP_NULL },
/*e2*/ { "DUP1", OP_NULL }, { "ABR", OP_NULL },
/*e4*/ { "NGR", OP_NULL }, { "LNOT", OP_NULL },
/*e6*/ { "IND", OP_B }, { "INC", OP_B },
};
static uint16 UB(t_value arg)
{
return arg & 0xff;
}
static uint16 DB(t_value arg)
{
return UB(arg);
}
static int16 W(t_value arg1, t_value arg2)
{
uint16 wl = arg1 & 0xff;
uint16 wh = arg2 & 0xff;
return wl | ((wh << 8) & 0xff00);
}
static int16 SW(t_value arg1, t_value arg2)
{
return W(arg1,arg2);
}
static int16 SB(t_value arg)
{
int16 w = arg & 0xff;
if (w & 0x80) w |= 0xff00;
return w;
}
static uint16 B(t_value arg1, t_value arg2, int* sz) {
uint16 wh = arg1 & 0xff;
uint16 wl;
if (wh & 0x80) {
wl = arg2 & 0xff;
wl |= ((wh & 0x7f) << 8);
*sz = 2;
return wl;
} else {
*sz = 1;
return wh;
}
}
t_stat print_hd(FILE *of, t_value val, t_bool hexdec, t_bool isbyte)
{
uint16 data = isbyte ? (val & 0xff) : (val & 0xffff);
if (hexdec)
fprintf(of,"%0xh",data);
else
fprintf(of,"%d",data);
return SCPE_OK;
}
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val,
UNIT *uptr, int32 sw)
{
uint16 op, arg1, arg2, arg3;
int16 sarg;
t_stat size = 0;
int optype, sz;
t_bool hexdec = (sw & SWMASK('H')) ? TRUE : FALSE;
addr = ADDR_OFF(addr);
op = val[0];
if (op > 0xe7) return SCPE_ARG;
optype = optable[op].flags;
if (optype > OP_ERROR) {
fprintf(of,"%-8s", optable[op].name);
switch (optype) {
case OP_NULL:
break;
case OP_UB:
size = 1; arg1 = UB(val[1]);
print_hd(of, arg1, hexdec, FALSE);
break;
case OP_W:
size = 2; sarg = W(val[1],val[2]);
print_hd(of, sarg, hexdec, FALSE);
break;
case OP_AB:
arg1 = B(val[1],val[2], &sz); size = sz;
fprintf(of,"#%x", arg1*2);
break;
case OP_B:
arg1 = B(val[1],val[2], &sz); size = sz;
print_hd(of, arg1, hexdec, FALSE);
break;
case OP_DBB:
arg1 = DB(val[1]);
arg2 = B(val[2],val[3], &sz); size = sz+1;
print_hd(of, arg1, hexdec, TRUE); fputc(',',of);
print_hd(of, arg2, hexdec, FALSE);
break;
case OP_UBB:
arg1 = UB(val[1]);
arg2 = B(val[2],val[3], &sz); size = sz+1;
print_hd(of, arg1, hexdec, TRUE); fputc(',',of);
print_hd(of, arg2, hexdec, FALSE);
break;
case OP_BUB:
arg1 = B(val[1],val[2], &sz); size = sz+1;
arg2 = UB(val[sz+1]);
print_hd(of, arg1, hexdec, FALSE); fputc(',',of);
print_hd(of, arg2, hexdec, TRUE);
break;
case OP_SB:
size = 1; sarg = SB(val[1]);
fprintf(of,"#%x", addr+sarg+2);
break;
case OP_SW:
size = 2; sarg = SW(val[1],val[2]);
fprintf(of,"#%x", addr+sarg+3);
break;
case OP_DBUB:
size = 2; arg1 = DB(val[1]);
arg2 = UB(val[2]);
print_hd(of, arg1, hexdec, TRUE); fputc(',',of);
print_hd(of, arg2, hexdec, TRUE);
break;
case OP_UBUB:
size = 2; arg1 = UB(val[1]);
arg2 = UB(val[2]);
print_hd(of, arg1, hexdec, TRUE); fputc(',',of);
print_hd(of, arg2, hexdec, TRUE);
break;
case OP_UBDBUB:
size = 3; arg1 = UB(val[1]);
arg2 = DB(val[2]);
arg3 = UB(val[3]);
print_hd(of, arg1, hexdec, TRUE); fputc(',',of);
print_hd(of, arg2, hexdec, TRUE); fputc(',',of);
print_hd(of, arg3, hexdec, TRUE);
break;
case OP_DB:
size = 1; arg1 = DB(val[1]);
print_hd(of, arg1, hexdec, TRUE);
break;
}
return -size;
} else {
fprintf(of,"%-8s","DB"); print_hd(of, op, hexdec, TRUE);
return SCPE_OK;
}
}
/* Symbolic decode
Inputs:
*of = output stream
addr = current PC
*val = pointer to data
*uptr = pointer to unit
sw = switches
Outputs:
return = status code
*/
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
UNIT *uptr, int32 sw)
{
t_addr off;
T_FLCVT t;
int ch;
t_bool hexdec = (sw & SWMASK('H')) ? TRUE : FALSE;
if (sw & SWMASK('M') && !ADDR_ISWORD(addr)) {
return fprint_sym_m(of, addr, val, uptr, sw);
}
if (sw & SWMASK('B')) { /* as BYTE */
if (ADDR_ISWORD(addr)) {
fprint_val(of, (val[0]>>8) & 0xff, cpu_dev.dradix, 8, PV_RZRO);
fprintf(of, ",");
fprint_val(of, val[0] & 0xff, cpu_dev.dradix, 8, PV_RZRO);
} else
fprint_val(of, val[0], cpu_dev.dradix, 8, PV_RZRO);
return SCPE_OK;
}
if (sw & SWMASK('C')) { /* as CHAR */
if (ADDR_ISWORD(addr)) {
ch = val[0] & 0xff;
fprintf(of, isprint(ch) ? "%c," : "%02x,", ch);
ch = val[0]>>8;
fprintf(of, isprint(ch) ? "%c" : "%02x", ch);
} else {
ch = val[0] & 0xff;
fprintf(of, isprint(ch) ? "%c" : "%02x", ch);
}
return SCPE_OK;
}
if (sw & SWMASK('W')) { /* as WORD */
if (ADDR_ISWORD(addr)) {
fprint_val(of, val[0], cpu_dev.dradix, 16, PV_RZRO);
off = ADDR_OFF(addr);
if (off > (reg_bp+MSCW_SZ-1))
fprintf(of," (GLOBAL+%d)", off - reg_bp - MSCW_SZ + 1);
else if (off >= reg_mp && off <= (reg_mp+OFFB_MSSEG))
fprintf(of," (MP+%d)", off - reg_mp);
else if (off > (reg_mp+MSCW_SZ-1))
fprintf(of," (LOCAL+%d)", off - reg_mp - MSCW_SZ + 1);
else if (off >= reg_sp && off < reg_spupr)
fprintf(of," (SP+%d)", off - reg_sp);
} else {
fprint_val(of, val[0], cpu_dev.dradix, 8, PV_RZRO);
fprint_val(of, val[1], cpu_dev.dradix, 8, PV_RZRO);
}
return SCPE_OK;
}
if (sw & SWMASK('F')) { /* as FLOAT */
t.i[0] = val[1];
t.i[1] = val[0];
fprintf(of, "%12.6e", t.f);
return -1;
}
if (sw & SWMASK('S')) { /* as semaphore */
fprintf(of, "SEM(count=%d, waitq=$%04x)", val[0], val[1]);
return -1;
}
if (sw & SWMASK('M')) { /* as MSCW */
dbg_dump_mscw(of, val[0]);
return SCPE_OK;
}
if (sw & SWMASK('T')) { /* as TIB */
dbg_dump_tib(of, addr);
return SCPE_OK;
}
return SCPE_ARG;
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
Outputs:
status = error status
*/
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
{
return SCPE_ARG;
}

2
PDQ-3/run.cmd Normal file
View file

@ -0,0 +1,2 @@
@echo off
pdq3.exe testhdt.sim

125
PDQ-3/testhdt.sim Normal file
View file

@ -0,0 +1,125 @@
;set debug debug.log
set debug stdout
;set fdc debug=read
;set fdc debug=write
;set fdc debug=verbose
;set fdc debug=svc
;set fdc debug=imd
;set fdc debug=dma
;set fdc debug=dmavb
;set fdc debug=cmd
;set cpu exc
;set cpu debug=int
;set cpu debug=trace
;set cpu debug=write
;set cpu debug=read
;set cpu debug=fetch
;set cpu debug=stack
;set cpu debug=conc
;set con debug=svc
;set con debug=read
;set con debug=write
;set tim debug=read
;set tim debug=write
;set tim debug=svc
att con 8000
att fdc0 master.imd
set fdc0 wrtlck
set fdc1 disable
; HDT boot
;break f418:368
;break f418:36a
;break f418:218
; HDT:bootfd
;break f418:e0
; HDT CHK instruction: will fail if CPU serial is > 0x7fff
;break 2018:067d
;break 2018:070f
; entering PASCALSY
;break eb1e:10
; problem main loop in syscode1
;break dc26:1d0a
;break d488:b1b
;break d488:b55
; bug in SPR(4), does not save SP in TIB?
;break d488:bb8
;break d488:bc7
; problem with wait?
;break d488:0917
; interrupt debugging
;break d078:4f
;break d488:919
;break d488:ebe
;break dc26:ec3
;break d1bd:79
;break b80d:715
;break dc26:1d35
;break d488:806
;break d488:915
;break dc26:1d36
; SHELL handling
;break badf:98
;break badf:51
;break bbd2:1ba
;break bbd2:1be
;break bbd2:32a
; Ser_RawEmit
;break c964:5f2
;break d488:d80
;break c964:6be
; ticker interrrupts
;break d078:4f
;break d1bd:6e
; Start/Stop Process
;break d488:7f0
;break d488:92e
;break d488:934
;break d488:958
;break d488:0dd9
;break c964:756
;break c964:a6
;break c964:cf4
; waiting for DSR sem
;break c964:624
; Ser_Read
;break c964:466
;break c964:4f9
;break c964:4fa
;break c964:327
;break c964:59e
;break c964:323
;break d078:4c
;break d078:4f
;break d1bd:6a
;break d1bd:6d
;break d488:ed0
load hdt/CPU_C5.BIN
dep _ssr 80
dep _ses 80
do names.sim
boot cpu
set debug stdout

View file

@ -20,6 +20,10 @@
#### Updated HP2100 simulator from Dave Bryan.
#### Beta Sigma 5, 6 & 7 simulator from Bob Supnik
#### Beta SAGE-II and PDQ-3 simulators from Holger Veit
### New Host Platform support - HP-UX and AIX
### New Functionality

31
SAGE/FILES/68k-s133.sim Normal file
View file

@ -0,0 +1,31 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set cpu nostop
set cpu bios=s133.hex
set debug debug.log
;set debug stdout
break fe1ad6
break 7bd08
break 7def2
set timer1 debug=read
set timer1 debug=write
;set timer2 debug=read
;set timer2 debug=write
;set pic debug=read
set pic debug=write
set pic debug=irqin
set pic debug=irqout
;set fd debug=verbose
set fd debug=cmd
;set fd debug=seek
set fd debug=irq
set fd debug=state
;set fd debug=status
;set fd debug=rddata
set lp debug=rdc
set lp debug=rdb
set dip debug=wrc
att fd0 cpm68k12.imd
boot cpu

31
SAGE/FILES/68k-sii.sim Normal file
View file

@ -0,0 +1,31 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set cpu nostop
set cpu bios=sii.hex
set debug debug.log
;set debug stdout
break fe1ad6
break 7bd08
break 7def2
set timer1 debug=read
set timer1 debug=write
;set timer2 debug=read
;set timer2 debug=write
;set pic debug=read
set pic debug=write
set pic debug=irqin
set pic debug=irqout
;set fd debug=verbose
set fd debug=cmd
;set fd debug=seek
set fd debug=irq
set fd debug=state
;set fd debug=status
;set fd debug=rddata
set lp debug=rdc
set lp debug=rdb
set dip debug=wrc
att fd0 cpm68k12.imd
boot cpu

31
SAGE/FILES/68k-v204.sim Normal file
View file

@ -0,0 +1,31 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set cpu nostop
set cpu bios=v2-04.hex
set debug debug.log
;set debug stdout
break fe1ad6
break 7bd08
break 7def2
set timer1 debug=read
set timer1 debug=write
;set timer2 debug=read
;set timer2 debug=write
;set pic debug=read
set pic debug=write
set pic debug=irqin
set pic debug=irqout
;set fd debug=verbose
set fd debug=cmd
;set fd debug=seek
set fd debug=irq
set fd debug=state
;set fd debug=status
;set fd debug=rddata
set lp debug=rdc
set lp debug=rdb
set dip debug=wrc
att fd0 cpm68k12.imd
boot cpu

31
SAGE/FILES/68k-v22.sim Normal file
View file

@ -0,0 +1,31 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set cpu nostop
set cpu bios=v2-2.hex
set debug debug.log
;set debug stdout
break fe1ad6
break 7bd08
break 7def2
set timer1 debug=read
set timer1 debug=write
;set timer2 debug=read
;set timer2 debug=write
;set pic debug=read
set pic debug=write
set pic debug=irqin
set pic debug=irqout
;set fd debug=verbose
set fd debug=cmd
;set fd debug=seek
set fd debug=irq
set fd debug=state
;set fd debug=status
;set fd debug=rddata
set lp debug=rdc
set lp debug=rdb
set dip debug=wrc
att fd0 cpm68k12.imd
boot cpu

31
SAGE/FILES/68k-v23.sim Normal file
View file

@ -0,0 +1,31 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set cpu nostop
set cpu bios=v2-3.hex
set debug debug.log
;set debug stdout
break fe1ad6
break 7bd08
break 7def2
set timer1 debug=read
set timer1 debug=write
;set timer2 debug=read
;set timer2 debug=write
;set pic debug=read
set pic debug=write
set pic debug=irqin
set pic debug=irqout
;set fd debug=verbose
set fd debug=cmd
;set fd debug=seek
set fd debug=irq
set fd debug=state
;set fd debug=status
;set fd debug=rddata
set lp debug=rdc
set lp debug=rdb
set dip debug=wrc
att fd0 cpm68k12.imd
boot cpu

45
SAGE/FILES/68k.sim Normal file
View file

@ -0,0 +1,45 @@
;set cpu debug=int
;set cpu debug=exc
;set cpu debug=ctrace
;set cpu debug=btrace
set cpu 512k
set cpu nostop
set debug debug.log
;set debug stdout
;break fe1ad6
;break 7bd08
;break 7def2
;break 8d8
;break 794
;break 78076
;break 75612
;break 77ef4
;break 75618
;break 73518
;break 7353a
;set timer1 debug=read
;set timer1 debug=write
;set timer2 debug=read
;set timer2 debug=write
;set pic debug=read
;set pic debug=write
;set pic debug=irqin
;set pic debug=irqout
;set fd debug=verbose
;set fd debug=cmd
;set fd debug=seek
;set fd debug=imd
;set fd debug=irq
;set fd debug=state
;set fd debug=status
;set fd debug=rddata
;set fd debug=wrdata
;set lp debug=rdc
;set lp debug=rdb
;set dip debug=wrc
;set cons debug=read
;set cons debug=write
;set cons debug=irq
att fd0 cpm68k12.imd
boot cpu

71
SAGE/FILES/68kdbg.sim Normal file
View file

@ -0,0 +1,71 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set cpu nostop
set debug debug.log
;set debug stdout
break fe1ad6
;break 7bd08
; raise PICINT7 for fdcread
break 7def2
; softint7_fdcread
break 7db38
;fdcint6_callback
break 7d5ba
;fdc_read
break 7d832
;fdc_cb_reenable_pic7_2
break 7d82a
;fdc_reset
break 7d7f4
;fdc_sendcmd
break 7d454
;fdc_senseint
break 7d48e
;fdc_readstatus
break 7d544
;fdc_startdrive
break 7d6d6
;process_schedqueue
break 7c64c
;fdc_readid
break 7d956
;fdc_recalibrate_routine
break 7da14
;fdc_Recalibrate_done
break 7da60
;fdc_autointhandler
break 7d7d0
;handler_autoint6_default
break 7d7ec
;cancelschedule
break 7c614
;addschedule
break 7c5b0
;fdc_getstatus7
break 7d4dc
set timer1 debug=read
set timer1 debug=write
set timer2 debug=read
set timer2 debug=write
;set pic debug=read
set pic debug=write
set pic debug=irqin
set pic debug=irqout
;set fd debug=verbose
set fd debug=cmd
set fd debug=seek
;set fd debug=irq
;set fd debug=state
;set fd debug=status
;set fd debug=rddata
set lp debug=rdc
set lp debug=rdb
set dip debug=wrc
att fd0 cpm68k12.imd
boot cpu

95
SAGE/FILES/bin2sage.c.txt Normal file
View file

@ -0,0 +1,95 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define CRLF "\r\n"
#define BASE 0xfe0000
#define RECLEN 32
void putS0(FILE* out, const char* header)
{
int i, csum, c;
int len = strlen(header);
fprintf(out, "S0%02X0000", 2 + len + 1);
csum = 0;
for (i=0; i<len; i++) {
c = ((int)header[i]) & 0xff;
csum += c;
fprintf(out, "%02X", c);
}
fprintf(out, "%02X" CRLF, (~csum) & 0xff);
}
void putS8(FILE* out,int start)
{
int csum = 4 + ((BASE>>16) & 0xff) + ((BASE>>8) & 0xff) + (BASE & 0xff);
fprintf(out, "S804%06X%02X" CRLF, BASE & 0xffffff, (~csum) &0xff);
}
void putS2(FILE* out, int addr, unsigned char* data, int n)
{
int i, csum, c;
fprintf(out, "S2%02X%06X", 3 + n + 1, addr & 0xffffff);
csum = 3 + n + 1 + ((addr>>16) & 0xff) + ((addr>>8) & 0xff) + (addr & 0xff);
for (i=0; i<n; i++) {
c = data[i] & 0xff;
fprintf(out, "%02X", c);
csum += c;
}
fprintf(out, "%02X" CRLF, (~csum) & 0xff);
}
int main(int argc, char* argv[])
{
FILE *e,*out;
int c,i;
unsigned char eprombuf[65536];
int size;
if (argc != 3) {
fprintf(stderr,
"Convert a 16bit EPROM file into EXORMACS format, compatible to SIMH SAGE.\n"
"Usage: %s eprom.dat output.dat\n\n", argv[0]);
exit(1);
}
e = fopen(argv[1], "rb");
out = fopen(argv[2], "wb");
if (!e) {
fprintf(stderr, "Could not open %s\n", argv[1]);
exit(1);
}
if (!out) {
fprintf(stderr, "Could not open %s\n", argv[2]);
exit(1);
}
size = 0;
do {
if ((c = fgetc(e)) == EOF) break;
eprombuf[size++] = c;
} while (!feof(e));
printf("%s: Size = %d\n", argv[2], size);
fclose(e);
for (i=0; i<size; i+=2) {
c = eprombuf[i+1];
eprombuf[i+1] = eprombuf[i];
eprombuf[i] = c;
}
putS0(out, argv[2]);
i = 0;
for (i=0; i<size; i += RECLEN) {
putS2(out, BASE+i, eprombuf+i, RECLEN);
}
putS8(out, BASE);
fclose(out);
exit(0);
}

17
SAGE/FILES/cpm.sim Normal file
View file

@ -0,0 +1,17 @@
set cpu debug=int
set cpu debug=exc
set cpu nostop
set cpu 512k
;set debug debug.log
set debug con
break fe1ad6
;set fd debug=verbose
;set fd debug=cmd
;set fd debug=seek
;set fd debug=irq
;set fd debug=state
;set fd debug=status
;set fd debug=rddata
att fd0 cpm68k12.imd
boot cpu

BIN
SAGE/FILES/cpm11a.imd Normal file

Binary file not shown.

BIN
SAGE/FILES/cpm68k.imd Normal file

Binary file not shown.

BIN
SAGE/FILES/cpm68k12.imd Normal file

Binary file not shown.

View file

@ -0,0 +1,61 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define CRLF "\r\n"
#define BASE 0xfe0000
#define RECLEN 32
int main(int argc, char* argv[])
{
FILE *e,*o,*out;
int c,i;
unsigned char eprombuf[65536];
int size;
if (argc != 4) {
fprintf(stderr,
"Combine two 8bit-EPROM files into a single merged one\n"
"and output it in 16bit binary format.\n"
"Usage: %s even.dat odd.dat output.dat\n\n", argv[0]);
exit(1);
}
e = fopen(argv[1], "rb");
o = fopen(argv[2], "rb");
out = fopen(argv[3], "wb");
if (!e) {
fprintf(stderr, "Could not open %s\n", argv[1]);
exit(1);
}
if (!o) {
fprintf(stderr, "Could not open %s\n", argv[2]);
exit(1);
}
if (!out) {
fprintf(stderr, "Could not open %s\n", argv[3]);
exit(1);
}
size = 0;
while (!feof(e)) {
if ((c = fgetc(e)) == EOF) break;
eprombuf[size++] = c;
if ((c = fgetc(o)) == EOF) break;
eprombuf[size++] = c;
}
printf("%s: Size = %d\n", argv[3], size);
fclose(e);
fclose(o);
for (i=0; i<size; i++) {
fputc(eprombuf[i],out);
}
fclose(out);
exit(0);
}

105
SAGE/FILES/read_ucsd.c.txt Normal file
View file

@ -0,0 +1,105 @@
#include <stdio.h>
struct dir0 {
unsigned short dfirstblk;
unsigned short dflastblk;
unsigned short dfkind;
char length;
char dvid[7];
unsigned short deovblk;
unsigned short dnumfiles;
unsigned short dloadtime;
unsigned short dlastboot;
unsigned short padding;
};
struct dirn {
unsigned short dfirstblk;
unsigned short dflastblk;
unsigned short dfkind;
char length;
char dtid[15];
unsigned short dlastbyte;
unsigned short daccess;
};
unsigned short swap(unsigned short x) {
union u {
unsigned short x;
unsigned char c[2];
} u;
unsigned char s;
u.x = x;
s = u.c[0];
u.c[0] = u.c[1];
u.c[1] = s;
return u.x;
}
int main(int argc, char* argv[])
{
char name[17];
char cbuf[512];
char buf[512*4];
FILE* in,*out;
int i,n,k;
int b,e,l;
struct dir0* dir0;
struct dirn* dirn;
if (argc != 2) {
fprintf(stderr,"Usage: %s diskimage.bin\n",argv[0]);
exit (1);
}
if ((in=fopen(argv[1],"rb"))==NULL) {
fprintf(stderr,"Can't read %s\n",argv[1]);
exit(2);
}
/* read boot block (two sectors) */
printf("Extract boot record\n");
fread(buf,2,512,in);
out = fopen("bootrec.bin","wb");
fwrite(buf,2,512,out);
fclose(out);
/* read directory records */
fread(buf,4,512,in);
dir0 = (struct dir0*)buf;
dirn = (struct dirn*)(buf+26);
printf("Directory:\n");
printf(" firstblock=%d\n",swap(dir0->dfirstblk));
printf(" lastblock=%d\n",swap(dir0->dflastblk));
printf(" volumeid=");
for (i=0; i<dir0->length; i++) printf("%c",dir0->dvid[i]);
putchar('\n');
printf(" lastblock=%d\n",swap(dir0->deovblk));
printf(" numfiles=%d\n",swap(dir0->dnumfiles));
for (n=0; n<swap(dir0->dnumfiles); n++) {
if (dirn[n].dfkind) {
printf("\nFile=");
for (i=0; i<dirn[n].length; i++) printf("%c",dirn[n].dtid[i]);
putchar('\n');
b = swap(dirn[n].dfirstblk);
e = swap(dirn[n].dflastblk);
l = swap(dirn[n].dlastbyte);
printf(" firstblock=%d\n",b);
printf(" lastblock=%d\n",e);
printf(" filetype=0x%04x\n",swap(dirn[n].dfkind));
printf(" lastbyte=%d\n",l);
memset(name,0,17);
strncpy(name,dirn[n].dtid,dirn[n].length);
out = fopen(name,"wb");
fseek(in,b*512,0);
for (k=0; k<(e-b)-1; k++) {
fread(cbuf,1,512,in);
fwrite(cbuf,1,512,out);
}
fread(cbuf,1,l,in);
fwrite(cbuf,1,l,out);
fclose(out);
}
}
}

138
SAGE/FILES/readcpm.c.txt Normal file
View file

@ -0,0 +1,138 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef struct direntry {
unsigned char une[12];
#define d_user une[0]
#define d_name une[1]
#define d_ext une[9]
u_short d_fext;
u_char d_fill;
u_char d_last;
u_short d_blks[8];
} DIR;
#define UNUSED 0xE5
#define DIROFFSET 0x2000
#define DIRBLKS 16
#define BLKSTART (DIROFFSET+DIRBLKS*128)
#define CLSTSIZE 2048
typedef struct fileentry {
char f_name[30];
u_short f_fext;
u_char f_last;
u_short f_blks[200];
} FENTRY;
void makename(char* name, DIR* dir)
{
int i;
char *p = name;
for (i=0; i<8; i++) {
if ((&dir->d_name)[i]==' ') break;
*p++ = (&dir->d_name)[i];
}
*p++ = '.';
for (i=0; i<3; i++) {
if ((&dir->d_ext)[i]==' ') break;
*p++ = (&dir->d_ext)[i];
}
*p = 0;
}
FENTRY* lookup(char* name, FENTRY* files)
{
FENTRY* nul=0, *p = files;
int i;
for (i = 0; i<64; i++) {
if (p->f_name[0]==0) {
if (nul==0) nul = p;
} else {
if (!strcmp(p->f_name,name)) {
return p;
}
}
p++;
}
if (nul==0) {
printf("File table full!\n");
exit(1);
}
return nul;
}
int main(int argc,char* argv[])
{
FILE *in,*out;
unsigned char cpmbuf[2048];
int i,k,n,s,ls;
char name[30];
FENTRY files[64], *fe;
DIR* dir;
if (argc != 2) {
fprintf(stderr,"Usage: %s cpmdisk.bin\n",argv[0]);
exit(1);
}
for (i=0; i<64; i++) {
files[i].f_name[0] = 0;
files[i].f_fext = 0;
files[i].f_last = 0;
memset(files[i].f_blks,0,sizeof(u_short)*200);
}
in = fopen(argv[1],"rb");
if (!in) {
perror("open file");
exit(1);
}
fseek(in,DIROFFSET,0);
for (i=0; i<DIRBLKS; i++) {
fread(cpmbuf,sizeof(DIR),4,in);
for (k=0; k<4; k++) {
dir = (DIR*)(cpmbuf+k*sizeof(DIR));
if (dir->d_user == UNUSED) continue;
makename(name,dir);
fe = lookup(name,files);
strcpy(fe->f_name,name);
if (dir->d_fext >= fe->f_fext) {
fe->f_fext = dir->d_fext;
fe->f_last = dir->d_last;
}
for (n=0; n<8; n++) {
fe->f_blks[dir->d_fext*8+n] = dir->d_blks[n];
}
}
}
for (i=0; i<64; i++) {
if (!files[i].f_name[0]) continue;
printf("File %s: (last=%d)\n",files[i].f_name,files[i].f_last%16);
FILE* out = fopen(files[i].f_name,"wb");
for (k=0; k<199; k++) {
n = files[i].f_blks[k];
if (n==0) break;
fseek(in,BLKSTART+CLSTSIZE*(n-1),0);
fread(cpmbuf,1,2048,in);
ls = files[i].f_last % 16;
if (!ls) ls = 16;
s = files[i].f_blks[k+1]==0 ? ls*128 : CLSTSIZE;
fwrite(cpmbuf,1,s,out);
printf("%d ",files[i].f_blks[k]);
}
printf("\n");
fclose(out);
}
exit(0);
}

258
SAGE/FILES/s133.hex Normal file
View file

@ -0,0 +1,258 @@
S00B0000733133332E68657882
S224FE00000000040000FE0034600003AE600003A2600007B060000334600002DE600002B68B
S224FE0020600002E4600002EA600016E4600016E6600002204E70203CFFFFFFFFB0BCFFFF73
S224FE0040FFFF664E220046812E402A412C4F4E65284E4E6B244C224B204A2E092C082A07E9
S224FE0060280626052404C741D2826A266524672252816B1E641C661A691892BC8000000053
S224FE00806810B2BC800000006608E38065B6660201C16676018157C9FFFA0141676C223CF7
S224FE00A000001234C2FCFEDC82FC1234B2BC0000FEDC6656428008C0000008C0000108C07C
S224FE00C0000208C0000308C0000408C0000508C0000608C000070880000808800009088071
S224FE00E0000A0880000B0880000C0880000D0880000E0880000FB0BC000000FF660C7207B4
S224FE0100034057C9FFFC4A8067044E7227004FF8040011FC0092C02711FC0038C02511FC5A
S224FE01200092C06711FC0031C06543FA00066000012611FC0001C06749FA19574BFA0006A3
S224FE014060001858307C000072014841323CFFFE224145FA000660001798663047FA002407
S224FE016021CB000872024841D3C1303CA5A53280B051660E46403280B05166064640D3C15B
S224FE018060EC93C145FA000660001766303C00BF41F80100429851C8FFFC548921C901007F
S224FE01A04E6121C9014A21C901426100032A11FC0000C0676100011E41FA18B96100013A41
S224FE01C032380100E2415341C2FC000541FB100C61000126610000FE60143132384B00326C
S224FE01E035364B003338344B003531324B007228740208380006C0216702725011C201C67D
S224FE020011C101C7423801CA11C201CE11C101CF11FC000101D27206610000861038C0214F
S224FE0220C07C00306706B07C0020671E21F80100014A21F80100014231FC2700014E41FA71
S224FE0240001221C801466000057A42676100160860DA4E4F60FC41F8C0734200108011FCD4
S224FE02600076C007E01810801238C021E0181080706E080100036702707E10BC0040024173
S224FE0280000711FB1014C003108011FC0000C003E01810BC00254ED10280402010080402F9
S224FE02A041F8C0334240108011FC00B6C007E018108011FB10E4C005E018108011C0C00508
S224FE02C0E01810BC0040E01810BC004EE01810BC00274E752F00700D6170700A616C420051
S224FE02E061686166616461626160201F4E752F0070206156201F4E753F0010186704614A2B
S224FE030060F8301F4E75E9186126E91861224E753F017203E958611851C9FFFA321F4E750B
S224FE03203F017207E998610851C9FFFA321F4E753F000200000FB03C000963040600000737
S224FE0340060000306104301F4E754A380104662C3F01323CFFFF08380002C07356C9FFF89D
S224FE0360670811C0C071321F4E7548E7C0C043FA00066000FEE24CDF030360D64E4A4E7501
S224FE03804A38010466262F011238C0730801000167F61038C071020100386604221F4E7511
S224FE03A011FC0035C073700761A060DC4E494E7508380001C0734E7561C6088000070C00BE
S224FE03C000616D0A0C00007A6E04088000054E756116611461126110610E610C610A61087A
S224FE03E06106610461024E7148F87FFF01064E6821C8014A2A1F41FAFFD89A887016BA8020
S224FE04006256BA3C00046206381F261F341F31DF014E21DF014621CF01424FF804000C059B
S224FE0420001467000B486E000AC00C050012660611FC0001C06746FC270011FC0038C0255C
S224FE044008B8000601504238010470FF51C8FFFE43FA000A6000FE00428560C249FA159206
S224FE04604BFA00066000153449FA1694D8F450004BFA000460EE49FA169A4BFA000460E465
S224FE04802038014630780152610009FE6100FE460C050012660611FC0000C0670C050004DA
S224FE04A06200032041FA16F26100FE4E30046100FE6041FA16EF6100FE4020036100FE620E
S224FE04C041FA16EC6100FE3230026100FE446100FE04600002EE41F8000843FA14EC45FA06
S224FE04E0FB204280301967186B06D08A20C060F2424112003019D08A20C051C9FFFC60E2E8
S224FE05004E75225F02800000000FD080D089C1893251D3C04ED148E780B02478000847FA97
S224FE0520001421CB0008101121CA00084CDF0D01B0004E75508F321F46C141FA14C2610047
S224FE0540FDB8588F2009307801526100093C21CA00084CDF0D01000000014E750838000101
S224FE0560C0734E752F00703A6100FDE0201F6100FD7E4E752F00702C6100FDD0201F4E7592
S224FE05802F0070076100FDC4201F4E75C03C007F0C0000206D060C00007E6D02702E4E751A
S224FE05A02F092F01224842816100FE0E0C00001B6700006E0C000012670000680C00000D34
S224FE05C0674A0C000008661AB3C867DC6100FD7C6100FD1C6100FD7451C9FFF25389528234
S224FE05E060C40C00007F6614B3C867BC61585389528210116100FD54544160AC611A428116
S224FE060053826B0812C06100FD42609C610A421912C0221F225F4E758281673C4281602C0F
S224FE0620224842812F0870236100FD206100FCA6B3C86700000C10186100FD10B3C866F6E4
S224FE0640205F6000FF648281660E72013F00103C005C6100FCF6301F4E75428010188000B5
S224FE0660660253884E7561F28000670A0C00002067040C00002C4E7561E067080C000020BF
S224FE068067F653884E7561D2244942411219B011568957C9FFFA6600011C1021E158102137
S224FE06A0D4C04ED2428161BE6736040000306D2A0C0000096F0C040000076D060C00000F10
S224FE06C06E18E999484010010200000F660C48408200848267D0B48164CC428053804E75EF
S224FE06E0C1414E752F036190428395CA6100FF78670000480C00002367360C0000246708F9
S224FE0700347801525388602A6100FF5C6700002C0400003065240C000004641E244093C914
S224FE07206100FF44670000180C00002B660C6002528342826100FF6E670257832240D5CADD
S224FE0740D5CAD4FC0154D3D2201FC14380804E752F0242826100FF22670000520C000027C4
S224FE0760671C0C00002E674624016100FF386B06241F92814E75241F428153814E756100C7
S224FE0780FEDA6100FED6670000200C0000276712E19A4A0266E0D480828167E6B28264E2EB
S224FE07A060D46100FEC266CEC14260C47001241F22004E756100FB38703F6100FB8E61005F
S224FE07C0FDC04FF8040042B801546100FB080838000601506700000870546100FB6E363859
S224FE07E00152670C70246100FB6210036100FB42703E6100FB56742841F801886100FDA26F
S224FE080043FA09FE6100FE8060B843FA0A1C6000FE766100FE642838017E3878018210106E
S224FE0820670E6100FEC0668C2809284A31CA01826100FE46327C01001010670A6100FEA624
S224FE08406B00FF726704D3C45389528921C9017E2A09611C6718280B6100FD0267F4610019
S224FE0860FB580C00001367F60C00000366E44E756100FA6220046100FAA86100FA722004B5
S224FE088090946100FA9C6100FCDC760F2644C7496100FC84C7496600FF1C101B6100FA68A2
S224FE08A008030000660000066100FA44BA8B57CBFFDE6100FA3A760F2644101B6100FCCE01
S224FE08C06100FA88BA8B57CBFFF24E7543F80154323C20247403601443F80126323C2041B9
S224FE08E0600843F80106323C204474076100FD6C6718903C00306B00FEBC1800B8026C0056
S224FE0900FEB461226100F9CE4E754284611852846100F9DC0C04000466046100F9D2612E30
S224FE0920B8026DEA4E75616842833001E0880C000020670000066100FA1210016100FA0C3B
S224FE09408683660610046100F9E86100FC182004E5804A836A0A303100006100F9B46008B3
S224FE0960203100006100F9BA4E756100FCEE6600FE446100FF646100FF6A61186108613256
S224FE09806104611E4E756100F9666100F9624E756000F94261FA43F80146323C5043601C79
S224FE09A061EE76FF43F8014E223C00005352600E61DE43F8014A223C00005553760142846D
S224FE09C06100FF684E757C00600001566000FDF443FA08726000FCB06100FD0A6600FDD6A1
S224FE09E060046100FB9C2809284A2A0454856100FE806100FB7041F80188243C00000028F9
S224FE0A006100FB9E428110106716223C0000FFFF6100FD3E6BCC6E0A13400001E08012808C
S224FE0A2054890C01002E66BE4E7543F80154323C202474047A01601643F80126323C2041D8
S224FE0A40600843F80106323C2044740842856100FC0A671A903C00306B00FD5AB0056B000E
S224FE0A60FD54B0026C00FD4E4282610E4E75200561085280B0026DF84E7542832F023A0158
S224FE0A8028002C00E5864A82660E6100FBEC4A10662260046100FAEA32056100F838610058
S224FE0AA0FE8A6100FAC0742841F801886100FAF21010671C42816100FC986BD866000012CF
S224FE0AC086836A0833806000600000062380600032051004241F4E756100FB806600FCD6B7
S224FE0AE06100FF566100FF5C6106611E610E4E7543F80146323C50436000001843F8014EE4
S224FE0B00323C535276FF6000000C43F8014A323C55537601428242806100FF624E757CFF45
S224FE0B207A0242806100FB3467144486903C00306B00FC82B03C00026E00FC7A3A00360078
S224FE0B4060046100FA3C3643D7CB284BD7CB4A866B0A675A6100FB224A106614616A6100E3
S224FE0B60FA04742841F801886100FA366100FB0A101067320C00002E660607B8015060262A
S224FE0B806100FB626BBC6100FAF0243C0000FFFF6100FB126BAC426C01723940017807F82D
S224FE0BA00150274901605243B6456F9A4E75611860F4427265616B706F696E742000496E01
S224FE0BC061637469766500006100F70A41FAFFE46100F72610036100F7586100F9880738B4
S224FE0BE00150660A41FAFFD86100F70E4E75202B01606100F72C6100F6F670286100F74C3D
S224FE0C00302C01786100F70A6100F96A302C01726100F6FE70296100F7324E7543FA064247
S224FE0C206000FA64243C000000FF613A6600FB861A00E1401005600C243C0000FFFF612671
S224FE0C406600FB723A00484030056008428261166600FB626100F8C06600FB5AE19812C042
S224FE0C60538466F04E752F026100FA7A661828096100FA72C9896B0E6E0498895284221F8A
S224FE0C806100FACE4E75225F4E7543FA05DE6000F9F643FA05E06000F9EE6100FA48660040
S224FE0CA0FB1420096100F67A6100F8BA10116100F6564E756100FA2E6600FAFA3C0908064E
S224FE0CC000006600FAF020096100F6566100F89630116100F63C4E7543FA05A16000F9A881
S224FE0CE06100FA026600FACE223C000000FF6100FA606600FAC012804E756100F9E8660031
S224FE0D00FAB43C09080600006600FAAA223C0000FFFF6100FA3C6600FA9C32804E75610000
S224FE0D20F95874076100F97E6B00FA8A22006000F57008B80005015043FA05486000F948F5
S224FE0D40740261000120426A017251CAFFF661226600FA6208F80006015008F80007015075
S224FE0D601038015002000007660608B800060150604C6100F9041010670A6100F968660C7C
S224FE0D8021C9014608F800060150B0004E756100F54443FA04F56000F8EE083800060150A8
S224FE0DA0661C4E7508F800050150600608B80005015061BE6600F9FE08B8000701502C3821
S224FE0DC00146284608060000671641FA00706100F528307801522006610000AE6000F9E43A
S224FE0DE0224C6100F7326600F9CC3C38014E08380006015066207400616A6B00F9B8670C1F
S224FE0E003551016C32BC4E4F0886000F52420C42000366E4600408C6000F3014B07C4E4F37
S224FE0E2066040886000F2078014A4E602E7801422F0C3F064CF87FFF01064E73496C6C659E
S224FE0E4067616C2070726F6772616D20737461727420616464726573733A200008B80006CF
S224FE0E6001504E7542803242D3C92449D3C905380150670E226901606100F69C6600000632
S224FE0E8052804E7553804E756100F4966100F4602F0070286100F4B470246100F4AE3008E5
S224FE0EA06100F48E6100F6BED1C8D1C8201F90A801546100F46C70296100F4904E750D0A20
S224FE0EC0556E657870656374656420747261636520636F6E646974696F6E2061743A200095
S224FE0EE054726163653A2000083800060150660641FAFFCC6016083800070150670A08B85E
S224FE0F00000601506000FEB841FAFFD6203801466100F3E62840307801526100FF6C6100E8
S224FE0F20F644224C6100F5F0660630116100F3E2083800050150670A41F801884210610061
S224FE0F40FA2A6000F87E0D0A556E657870656374656420627265616B20706F696E743A209F
S224FE0F6000000D0A427265616B3A200042854286283801465584760008380007015066068F
S224FE0F8041FAFFC4602C74026100FEDA6F1CB3C4661476023A2A01723C2A0178BC456706FD
S224FE0FA052453545017232AA016C51CAFFDC41FAFFB220380146908321C00146BC4566003E
S224FE0FC0FD946000FF4C43FA02D26000F6BA11FC000101BB49F8C031606E423801BB49F870
S224FE0FE0C071428574016100F6BC6B00F7C83C00243C0000FFFF6100F6AC6B00F7B83F004E
S224FE10006100F6E26600F7AE2F0942826100F6966B00F7A22F003F064A856706610006F68F
S224FE10206004610006EA6700000E41FA000C6100F2C86100F2D24E750D0A4469736B206512
S224FE104072726F723A20000061720C000051670000AC0C00005366F0420561601E006100EF
S224FE106000A81C01550642816100009E6100009A26410C070030660E4A0667066100008ACA
S224FE108060F6616060C20C0700326612220B6100007826414A0667EA616E16C160F60C073A
S224FE10A0003167F00C07003966524A06664E613441FA095D6100F2426000F708082C00013E
S224FE10C0000267081014088000074E754A3801BB67EA6100F2DC67E46100F2DE0C0000518F
S224FE10E066DA4E756122460566024E75588F41FA093D6100F2046000F6CA508F41FA091BD4
S224FE11006100F1F66000F6BC61086106DA0153064E7561A80C0000306DE00C0000396E0A5C
S224FE112004000030E989D2004E750C0000416DCA0C0000466EC45F0060E643FA01576000CF
S224FE1140F5467A016000FE9E6000F67843FA01566000F53453797374656D207265696E6933
S224FE11607469616C697A696E672E2E2E2E0041FAFFE46100F1846000EEBC42801010670A98
S224FE118074016100F5206B00F62C3F00610006C84E754E7542801010670A74036100F506BA
S224FE11A06B00F61231C001524E756100F5386600F60428096100F52E6B00F5FAC9896604F9
S224FE11C09889600253846500F5EC26496100F5166600F5E27201B7C96406D3C4D7C472FF54
S224FE11E06100F3346B00F5CEC34B6100F32AC34B6B00F5C21293D3C1D7C151CCFFE44E75E6
S224FE12000C440AF653D0F7461CFA2494FF4DAAFF508AFA548EFB4732FB573AFF4CC6FD0094
S224FE12209AFB494CFF41CCF7084DEAF55242F744BAF641B0F6506CF75378F75588F724A4D3
S224FE1240F6429EF7084D94F75294F844FEF741F4F750ACF853B8F855C6F824E6F742DAF87C
S224FE12600242C4F957D8F94CECF9024928FA4F6EFA53B4FA014226FA5740FA014265FA57FF
S224FE12807FFA014FBEFA43CCFA024223FB45D3FB521BFB0141B5FE46AFFE024134FD5440F4
S224FE12A0FD4648FD0346D6FE48EEFE47EEFE53CAFE00441BF7005453540043484700434C52
S224FE12C05200534554004F524900414E4449535542494144444942000000454F5249434D81
S224FE12E050492E4200002E5700002E3F00002E4C00004E454758434C52004E4547004E4FEC
S224FE13005400000000005453540054524150545241504C494E4B554E4C4B524553454E4FD9
S224FE1320500053544F5052544500344537345254530054524150525452004A5352004A4D97
S224FE1340500043484B004C45410044495655444956534D554C554D554C5354004600484975
S224FE13604C53434343534E45455156435653504C4D4947454C5447544C454F520000535571
S224FE13804200454F5200434D5000414E440041444400534243445355425800000000434DB8
S224FE13A050414142434441444458415352004C535200524F5852524F520041534C004C53DA
S224FE13C04C00524F584C524F4C0048E760401219143C00AD1038C0510800000756CAFFF618
S224FE13E0671A08000006661411D9C053740951CAFFFE530166DA4CDF02064E7511FC0001B7
S224FE140001C560F248E7604043FA07B461BC6624720243F801C36174661A123801C302016A
S224FE142000C0670C08010006670472036002720211C101C54CDF02064E7548E760407207DB
S224FE144043F801BC42116144663C123801BC020100C0672E0801000667267205103801BD7F
S224FE1460E208651E7206E40865187207E40865127208E208650C7209E4086506720A6002BA
S224FE1480720211C101C54CDF02064E75343C10FE1038C0510800000756CAFFF667160800C7
S224FE14A00006671012F8C053740951CAFFFE530166DA4E7511FC000101C54E752F0170026A
S224FE14C0484008380000C0636612538066F411FC0002C02711FC000401C5600C4A0266206E
S224FE14E012F8C053534166D611FC0001C02711FC0000C0276100FF44221F4A3801C54E7523
S224FE150011D9C053534166B660DE48E76040720143FA06A96100FEB46638740248420838BE
S224FE15200000C063660C538266F411FC000401C56020422C00036100FECC67160C3800032D
S224FE154001C5660E0C2C00500001660651C9FFC270034CDF02064E7548E76040720210388A
S224FE156001D6B02C0003674C43F801B032BC030F42290002137801D600036100FE4E6634FA
S224FE15807402484208380000C063660C538266F411FC000401C5601C6100FE6A660A197827
S224FE15A001D600034200600C6100FF60660651C9FFAE70034CDF02064E7500000000000044
S224FE15C00000423801C54A2C0000670000D23F077E0111FC000FC02711FC0000C02711FC50
S224FE15E00003C02743FA05D111FC000EC0276100FDDA663270064A2C00046702540011C09B
S224FE1600C02770FF51C8FFFE08380000C06367086100FDF2423801C56100FEF067120C38ED
S224FE1620000301C5670451CFFFAA3E1F70014E7570024840538066FC43FA05866100FD8C38
S224FE164066E4343CFFFE1038C0510800000756CAFFF6660E11FC0002C02711FC000401C512
S224FE166060C86100FDD666BE4240103801C267260C0000026E2067067210742060047208D0
S224FE1680740EE1483940000619410002194200053E1F42004E7511FC000901C5608C11FC2A
S224FE16A0000B01C54E754A2C0000675A4281323C020082EC00064282343801DEC4C142815E
S224FE16C0122C000284C14241082C000000006604E24AE31111C101D711C201D6B42C00010C
S224FE16E06C244842122C00029202C2EC0006B2B801E06F04223801E0520211C201D831C15A
S224FE170001DC42004E7511FC000B01C54E75423801DA600611FC000101DA225F49F801C616
S224FE1720301F670449F801CE21DF01E021DF01E431DF01DE2F097E034A6C0006660000FE4E
S224FE17406100FE80660000E24AB801E0670000DA11FC0003C0274A3801DA672C0838000113
S224FE1760C063670A11FC000C01C5600000BC102C0001E208B03801D66F0811FC000DC02779
S224FE1780600611FC000CC0276100FF1C6600009A6100FDC6667443F801B0303C09454A383E
S224FE17A001DA6602524032C0103801D7E50812C012F801D612F801D712F801D8302C000678
S224FE17C0E04812C012EC000212EC000512FC00FF43F801B06100FBF46630227801E44281E8
S224FE17E0323801DC143801DA6100FCD2661C303C032051C8FFFED3B801E493B801E082FC08
S224FE18000200D37801DE6000FF405307671A103801C50C0000016700FF280C0000036708F8
S224FE18200C0000046600FF2270074A2C00046702540011C0C027103801C54E7570064A2CEB
S224FE184000046702540011C0C02770024840538066FC6000FEF46100EC7E6100EA7841FAC2
S224FE1860024A6100EA946100EA6C4267307C04002F082F083F2F000E6100FE946612307C29
S224FE188004000C58424F663C0C584F5466364ED06100EA42103801C50C000004673041FA6C
S224FE18A0019B6100EA546100EA5E41FA01AC6100EA48102C00046100EA786100EA18205FE1
S224FE18C0548F4ED041FA01836100EA2E60DC41FA01EE6100EA246100EAE06100E9F80C007E
S224FE18E000516600FF7241FA01F76100EA0C60BA264842804281468126804A93661C2681B3
S224FE1900B293661C26CBB7C963EE2648B7D3660E588BB7C963F642804ED222006002220B80
S224FE1920201349FA013F4BFA00066000006E2A0B4BFA00066000007049FA01454BFA0006B1
S224FE1940600000582A004BFA00066000005A49FA01344BFA0006600000422A014BFA0006C2
S224FE19606000004449FA01874BFA00066000002C49FA01354BFA00066000002070014ED249
S224FE19803E3CFFFF08380002C07356CFFFF8670611C6C0714ED64E7227001C1C67064DFACF
S224FE19A0FFFA60DC4ED57807E99D7C0FCC050C060009630406060007060600304DFA00044F
S224FE19C060BE51CCFFE44ED503D003D203D4800203D603D803E403D403D4800B03DA80068B
S224FE19E003DE03E0800E03DC03E2800F03DA000007455843455054494F4E3A20200007200B
S224FE1A004E4F204D656D6F72792061743A20004C6F616420446F6E650007426164204C6F2F
S224FE1A20616420436861726163746572000742616420436865636B73756D00074472697634
S224FE1A4065204572726F722000074E6F7420424F4F54204469736B00206F6E2064726976CB
S224FE1A6065200007424144204D656D6F7279206174200052414D2053697A65203D2000202A
S224FE1A806973200020696E7374656164206F6620000D0A5341474520494920537461727413
S224FE1AA0757020546573740D0A00426F6F74696E672066726F6D20466C6F70707900507562
S224FE1AC07420696E20424F4F54206469736B20616E642070726573732061206B65790007E8
S224FE1AE0426F6F742041626F72746564002028546573742041626F72746564290000001F5D
S224FE1B000027002B003300470052005C006A007A008F204572726F722061742000556E6B68
S224FE1B206E6F776E00427573004164647265737300496C6C6567616C20496E73747275632E
S224FE1B4074696F6E0041726974686D657469630050726976696C65676500526573657276A0
S224FE1B606564205452415000556E61737369676E6564205452415000556E61737369676E92
S224FE1B80656420496E746572727570740052414D205061726974790046756E6374696F6ECD
S224FE1BA03A200020204163636573733A20002020496E73743A20000303D1070207000108B4
S224FE1BC0024A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
S224FE1BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
S224FE1C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
S224FE1C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
S224FE1C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
S224FE1C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
S224FE1C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
S224FE1CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
S224FE1CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
S224FE1CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
S224FE1D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
S224FE1D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
S224FE1D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
S224FE1D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
S224FE1D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
S224FE1DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
S224FE1DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
S224FE1DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
S224FE1E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
S224FE1E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
S224FE1E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
S224FE1E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
S224FE1E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
S224FE1EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
S224FE1EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
S224FE1EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
S224FE1F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
S224FE1F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
S224FE1F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
S224FE1F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
S224FE1F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
S224FE1FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
S224FE1FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
S224FE1FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
S804FE0000FD

258
SAGE/FILES/sage-ii.hex Normal file
View file

@ -0,0 +1,258 @@
S00E0000736167652D69692E686578ED
S224FE0000000004000000003C600004286000041C6000085E6000037E6000032860000300FC
S224FE00206000032E60000334600018E6600018E86000026A14D801026000025C4E704FF859
S224FE0040040011FC0092C02711FC0038C02511FC0092C06711FC0031C065700072FF343C6F
S224FE006042D741F8C0FE3080308151CAFFFA43F8000045F87FFE343C34423011301030125A
S224FE008051CAFFF8343C06C541F8C00172084A10D0FC001051C9FFF851CAFFEE43FA00060A
S224FE00A0600001FE49FA1C514BFA0012200D4840303C00FE48402A4060001B3E49FA1C436B
S224FE00C04BFA000660001B321038C0216B64E60802400006303B00064EFB000200180024FF
S224FE00E0001800084238010449FA1CE94BFA078260001B0649FA1CED4BFA003860001AFA8A
S224FE010049FA1CF04BFA000660001AEE74FF720070001038C023460008000002670272FF30
S224FE0120E308024000064840204030C151CAFFFC60DA41FAFECC343C0FFF42004201D01870
S224FE0140D21851CAFFFA4A00671449FA1C6B4BFA000660001AA44A38C0216A0000D84A01B6
S224FE0160671449FA1C614BFA000660001A8C4A38C0216A0000C011FC0001C067307C000082
S224FE018072014841323CFFFE224145FA0006600019A8663047FA002421CB00087202484140
S224FE01A0D3C1303CA5A53280B051660E46403280B05166064640D3C160EC93C145FA000627
S224FE01C06000197667084A38C0216A000068303C00BF41F80100429851C8FFFC548921C96F
S224FE01E001004E6121C9014A21C901426100039611FC0000C0674A38C0216B1611FC0007C4
S224FE0200C06770FF51C8FFFE11FC0006C0676000FF226100010A41FA1AC161000126303802
S224FE02200100ED48610001A4704B61000168610000EE60044E72270072287402083800060A
S224FE0240C0216702725011C201C611C101C7423801CA11C201CE11C101CF11FC000101D2F1
S224FE02607206610000861038C021C07C00306706B07C0020671E21F80100014A21F80100CA
S224FE0280014231FC2700014E41FA001221C80146600005DE4267610017E660DA4E4F60FC7B
S224FE02A041F8C0734200108011FC0076C007E01810801238C021E0181080706E080100038E
S224FE02C06702707E10BC00400241000711FB1014C003108011FC0000C003E01810BC002532
S224FE02E04ED1028040201008040241F8C0334240108011FC00B6C007E018108011FB10E48C
S224FE0300C005E018108011C0C005E01810BC0040E01810BC004EE01810BC00274E752F0004
S224FE0320700D6170700A616C420061686166616461626160201F4E752F0070206156201F53
S224FE03404E753F0010186704614A60F8301F4E75E9186126E91861224E753F017203E9582B
S224FE0360611851C9FFFA321F4E753F017207E998610851C9FFFA321F4E753F000200000FC0
S224FE0380B03C0009630406000007060000306104301F4E754A380104662C3F01323CFFFF7F
S224FE03A008380002C07356C9FFF8670811C0C071321F4E7548E7C0C043FA00066000FEE2F8
S224FE03C04CDF030360D64E4A4E7548E7F000720032007400343C2710420382C266044A033A
S224FE03E067061001619450C34241484184FC000A66E84CDF000F4E754A38010466282F014E
S224FE04001238C0730801000167F61038C071020100386604221F4E7511FC0035C0737007E7
S224FE04206100FF7260DA4E494E7508380001C0734E7561C4088000070C0000616D0A0C0078
S224FE0440007A6E04088000054E7521C001067002604E21C001067004604621C001067006F5
S224FE0460603E21C001067008603621C00106700A602E21C00106700C602621C00106700EA5
S224FE0480601E21C001067010601621C001067012600E21C001067014600621C001067016E5
S224FE04A048F87FFE010A4E6821C8014A2A007016BA80625EBA3C00046206381F261F341F8C
S224FE04C031DF014E21DF014621CF01424FF804000C05001467000B686E000AD20C05001289
S224FE04E0660C11FC0001C06711FC0000C06770FFE01851C8FFFC46FC270011FC0038C02510
S224FE050008B8000601504238010443FA000A6000FD90428560BA49FA17364BFA00066000F2
S224FE052016D849FA18E0D8F450004BFA000460EE49FA18E64BFA000460E4203801463078C7
S224FE0540015261000A146100FDD60C0500046200032041FA194A6100FDEA30046100FDFC84
S224FE056041FA19476100FDDC20036100FDFE41FA19446100FDCE30026100FDE06100FDA0F2
S224FE0580600002EE41F8000843FA169C45FAFA724280301967186B06D08A20C060F2424123
S224FE05A012003019D08A20C051C9FFFC60E24E75225F02800000000FD080D089C189325101
S224FE05C0D3C04ED148E780B02478000847FA001421CB0008101121CA00084CDF0D01B0001D
S224FE05E04E75508F321F46C141FA16746100FD54588F2009307801526100095E21CA0008C1
S224FE06004CDF0D01000000014E7508380001C0734E752F00703A6100FD7C201F6100FD1A39
S224FE06204E752F00702C6100FD6C201F4E752F0070076100FD60201F4E75C03C007F0C0070
S224FE064000206D060C00007E6D02702E4E752F092F01224842816100FDDA0C00001B67004F
S224FE0660006E0C000012670000680C00000D674A0C000008661AB3C867DC6100FD18610029
S224FE0680FCB86100FD1051C9FFF25389528260C40C00007F6614B3C867BC6158538952824A
S224FE06A010116100FCF0544160AC611A428153826B0812C06100FCDE609C610A421912C001
S224FE06C0221F225F4E758281673C4281602C224842812F0870236100FCBC6100FC42B3C873
S224FE06E06700000C10186100FCACB3C866F6205F6000FF648281660E72013F00103C005C69
S224FE07006100FC92301F4E75428010188000660253884E7561F28000670A0C00002067048A
S224FE07200C00002C4E7561E067080C00002067F653884E7561D2244942411219B0115689F6
S224FE074057C9FFFA6600011C1021E1581021D4C04ED2428161BE6736040000306D2A0C0055
S224FE076000096F0C040000076D060C00000F6E18E999484010010200000F660C484082002B
S224FE0780848267D0B48164CC428053804E75C1414E752F036190428395CA6100FF78670011
S224FE07A000480C00002367360C0000246708347801525388602A6100FF5C6700002C0400CC
S224FE07C0003065240C000004641E244093C96100FF44670000180C00002B660C6002528308
S224FE07E042826100FF6E670257832240D5CAD5CAD4FC0154D3D2201FC14380804E752F0280
S224FE080042826100FF22670000520C000027671C0C00002E674624016100FF386B06241FC8
S224FE082092814E75241F428153814E756100FEDA6100FED6670000200C0000276712E19A26
S224FE08404A0266E0D480828167E6B28264E260D46100FEC266CEC14260C47001241F22005F
S224FE08604E756100FAD4703F6100FB2A6100FDC04FF8040042B801546100FAA40838000651
S224FE088001506700000870546100FB0A36380152670C70246100FAFE10036100FADE703E50
S224FE08A06100FAF2742841F801886100FDA243FA0AF26100FE8060B843FA0B136000FE762B
S224FE08C06100FE642838017E387801821010670E6100FEC0668C2809284A31CA0182610018
S224FE08E0FE46327C01001010670A6100FEA66B00FF726704D3C45389528921C9017E2A093B
S224FE0900611C6718280B6100FD0267F46100FB240C00001367F60C00000366E44E75610071
S224FE0920F9FE20046100FA446100FA0E200490946100FA386100FCDC760F2644C74961001D
S224FE0940FC84C7496600FF1C101B6100FA0408030000660000066100F9E0BA8B57CBFFDE04
S224FE09606100F9D6760F2644101B6100FCCE6100FA24BA8B57CBFFF24E7543F80154323C67
S224FE098020247403601443F80126323C2041600843F80106323C204474076100FD6C671AB2
S224FE09A0903C00306B00FEBC78001800B8026E00FEB261226100F9684E754284611852848E
S224FE09C06100F9760C04000466046100F96C612EB8026DEA4E75616E42833001E0880C0064
S224FE09E00020670000066100F9AC10016100F9A68683660610046100F9826100FC16200454
S224FE0A00E5800280000000FF4A836A0A303100006100F9486008203100006100F94E4E7585
S224FE0A206100FCE66600FE3C6100FF5C6100FF626118610861326104611E4E756100F8FAE3
S224FE0A406100F8F64E756000F8D661FA43F80146323C5043601C61EE76FF43F8014E223C4D
S224FE0A6000005352600E61DE43F8014A223C00005553760142846100FF624E757C006000F7
S224FE0A80015C6000FDEC4E7543FA095F6000FCA66100FD006600FDCC60046100FB92280933
S224FE0AA0284A2A0454856100FE766100FB6641F80188243C000000286100FB944281101006
S224FE0AC06716223C0000FFFF6100FD346BCC6E0A13400001E080128054890C01002E66BE77
S224FE0AE04E7543F80154323C202474047A01601643F80126323C2041600843F80106323C3C
S224FE0B002044740842856100FC00671A903C00306B00FD50B0056B00FD4AB0026C00FD44D3
S224FE0B204282610E4E75200561085280B0026DF84E7542832F023A0128002C00E5864A82C6
S224FE0B40660E6100FBE24A10662260046100FAE032056100F7CA6100FE826100FAB6742878
S224FE0B6041F801886100FAE81010672042816100FC8E6BD8660000160286000000FF8683C9
S224FE0B806A063380600060042380600032051004241F4E756100FB726600FCC86100FF526D
S224FE0BA06100FF586106611E610E4E7543F80146323C50436000001843F8014E323C5352CA
S224FE0BC076FF6000000C43F8014A323C55537601428242806100FF5E4E757CFF7A0242805E
S224FE0BE06100FB2667144486903C00306B00FC74B03C00026E00FC6C3A003600600461005B
S224FE0C00FA2E3643D7CB284BD7CB4A866B0A675A6100FB144A106614616A6100F9F6742878
S224FE0C2041F801886100FA286100FAFC101067320C00002E660607B8015060266100FB5470
S224FE0C406BBC6100FAE2243C0000FFFF6100FB046BAC426C01723940017807F80150274985
S224FE0C6001605243B6456F9A4E75611860F4427265616B706F696E742000496E6163746960
S224FE0C80766500006100F69841FAFFE46100F6B410036100F6E66100F97A07380150660A3A
S224FE0CA041FAFFD86100F69C4E75202B01606100F6BA6100F68470286100F6DA302C017833
S224FE0CC06100F6986100F95C302C01726100F68C70296100F6C04E7543FA072B6000FA5628
S224FE0CE0243C000000FF61426600FB781A00E1401005600C243C0000FFFF612E6600FB64A8
S224FE0D003A004840300560084282611E6600FB5441FA10646100F62C6100F8AA6600FB449F
S224FE0D20E19812C0538466F04E752F026100FA64661828096100FA5CC9896B0E6E049889C1
S224FE0D405284221F6100FAB84E75225F4E756100F5E86100F5E443FA06B76000F9D843FA7F
S224FE0D6006B96000F9D06100FA2A6600FAF620096100F5F86100F89C10116100F5D44E7533
S224FE0D806100FA106600FADC3C09080600006600FAD220096100F5D46100F878301161005E
S224FE0DA0F5BA4E7543FA067A6000F98A6100F9E46600FAB0223C000000FF6100FA42660070
S224FE0DC0FAA212804E756100F9CA6600FA963C09080600006600FA8C223C0000FFFF610009
S224FE0DE0FA1E6600FA7E32804E756100F93A74076100F9606B00FA6C22006000F4EE08B8C7
S224FE0E000005015043FA06216000F92A740261000124426A017251CAFFF661226600FA4440
S224FE0E2008F80006015008F8000701501038015002000007660608B80006015060506100CA
S224FE0E40F8E61010670A6100F94A660C21C9014608F800060150B0006100F4C44E75610095
S224FE0E60F4BE43FA05CA6000F8CC083800060150661C4E7508F800050150600608B8000530
S224FE0E80015061BA6600F9DC08B8000701502C380146284608060000671641FA00706100E0
S224FE0EA0F4A2307801522006610000AE6000F9C2224C6100F7106600F9AA3C38014E08386C
S224FE0EC00006015066207400616A6B00F99667083551016C32BC4E4F52420C42000366E8D9
S224FE0EE00886000F600408C6000F3014B07C4E4F66040886000F2078014A4E602E78014283
S224FE0F002F0C3F064CF87FFF01064E73496C6C6567616C2070726F6772616D207374617218
S224FE0F207420616464726573733A200008B8000601504E7542803242D3C92449D3C90538E8
S224FE0F400150670E226901606100F67A6600000652804E7553804E756100F4106100F3DAE1
S224FE0F602F0070286100F42E70246100F42830086100F4086100F69CD1C8D1C8201F90A8E2
S224FE0F8001546100F3E670296100F40A4E750D0A556E6578706563746564207472616365A9
S224FE0FA03A200054726163653A200000083800060150660641FAFFD8601608380007015068
S224FE0FC0670A08B8000601506000FEC441FAFFD5203801466100F36C284030780152610032
S224FE0FE0FF786100F62E224C6100F5DA661430116100F3686100F3426100F33E2C496100DF
S224FE1000FA86083800050150670A41F8018842106100FA0E6000F85A0D0A556E657870658B
S224FE10206374656420627265616B20706F696E743A2000000D0A427265616B3A2000428527
S224FE104042862838014655847600083800070150660641FAFFC4602C74026100FED86F1C09
S224FE1060B3C4661476023A2A01723C2A0178BC45670652453545017232AA016C51CAFFDC1D
S224FE108041FAFFB220380146908321C00146BC456600FD8E6000FF3E43FA03A56000F69627
S224FE10A011FC000101BB6004423801BB41FA0CDC6100F2906076428574016100F6966B0059
S224FE10C0F7A23C00243C0000FFFF6100F6866B00F7923F006100F6BC6600F7882F094282D6
S224FE10E06100F6706B00F77C2F003F064A85670E41FA0CA56100F24C6100081C600C41FAD9
S224FE11000C8A6100F23E610008086700000E41FA000C6100F22E6100F2384E750D0A4469E5
S224FE1120736B206572726F723A20000061740C000051670000C00C00005366F04205616212
S224FE11401E00610000BC1C0153064281610000B2610000AE26410C070030660E4A0667061B
S224FE11606100009E60F6617460C20C0700326614220B6100008C26414A0667EA610000825C
S224FE118016C160F40C07003167EE0C07003966644A066660614641FA0AD96100F1A660003F
S224FE11A0F6D04A3801BB672408380001C033670A1038C031088000074E756100F26E67E263
S224FE11C06100F2700C00005166D84E756100F22A0C00000D6700F1486000F1BA61224605DC
S224FE11E066024E75588F41FA0AAB6100F1566000F680508F41FA0A876100F1486000F6725F
S224FE120061086106DA0153064E7561960C0000306DE00C0000396E0A04000030E989D2004F
S224FE12204E750C0000416DCA0C0000466EC45F0060E643FA02046000F4FC7A016000FE7A55
S224FE12406000F62E43FA02036000F4EA202053797374656D207265696E697469616C697AFE
S224FE1260696E672E2E2E2E0041FAFFE26100F0D46000EDCA4280428710100C800000005294
S224FE128066063E3C010052881010670A74016100F4C26B00F5CE80473F00610007E24E752C
S224FE12A04E7542801010670A74036100F4A66B00F5B231C001524E756100F4D86600F5A45E
S224FE12C028096100F4CE6B00F59AC98966049889600253846500F58C26496100F4B66600E1
S224FE12E0F58241FA0AC06100F05A7201B7C96406D3C4D7C472FF6100F2CC6B00F566C34BD1
S224FE13006100F2C2C34B6B00F55A1293D3C1D7C151CCFFE44E7543FA01456000F4183F3CEF
S224FE132000016002426774016100F4286B00F5343F00243C0000FFFF6100F4186B00F5248A
S224FE13403F00427801CC427801D411FC000101DB3F172F3C000004002F3C000010003F2F9D
S224FE1360000C4A6F000E6706610005AC6004610005A0662A702E6100F01C08F8000101DB36
S224FE13806100F0A867CA6100F07011FC0007C02711FC0009C027423801DB5C8F4E7570589B
S224FE13A060D40D4416F553E6F64636F92400FF4D16FF50ACF954BCFA475CFA5790FE4CF6AE
S224FE13C0FC00C8FA49A2FE41E0F64574FF084DF3F45253F644C3F541B9F5507DF65389F63D
S224FE13E05599F624ADF542AFF6084DA7F652ABF74411F74107F750C3F753CFF755DDF72478
S224FE1400F9F642F1F70242DBF857EFF84C03F902494FF94F95F953DBF901424DF95767F93C
S224FE142001428CF957A6F9014FE5F943F3F902424EFA45FEFA5246FA014108FE4602FE02A3
S224FE14404161FC5469FC4677FC03462BFE4857FE4757FE531FFE01442CF6522CF60152C769
S224FE1460FE57C1FE5453540043484700434C5200534554004F524900414E44495355424982
S224FE14804144444942000000454F5249434D50492E4200002E5700002E3F00002E4C0000C1
S224FE14A04E454758434C52004E4547004E4F540000000000545354005452415054524150E2
S224FE14C04C494E4B554E4C4B524553454E4F500053544F5052544500344537345254530077
S224FE14E054524150525452004A5352004A4D500043484B004C4541004449565544495653CE
S224FE15004D554C554D554C535400460048494C53434343534E45455156435653504C4D49C1
S224FE152047454C5447544C454F52000053554200454F5200434D5000414E44004144440063
S224FE15405355424141444441534243445355425800000000434D50414142434441444458A9
S224FE1560415352004C535200524F5852524F520041534C004C534C00524F584C524F4C0056
S224FE158048E760401219143C00AD1038C0510800000756CAFFF6671A08000006661411D9E1
S224FE15A0C053740951CAFFFE530166DA4CDF02064E7511FC000101C560F248E7604043FAC4
S224FE15C0090461BC6624720243F801C36174661A123801C3020100C0670C080100066704CE
S224FE15E072036002720211C101C54CDF02064E7548E76040720743F801BC42116144663C35
S224FE1600123801BC020100C0672E0801000667267205103801BDE208651E7206E408651801
S224FE16207207E40865127208E208650C7209E4086506720A6002720211C101C54CDF020607
S224FE16404E75343C10FE1038C0510800000756CAFFF6671608000006671012F8C05374092D
S224FE166051CAFFFE530166DA4E7511FC000101C54E752F017002484008380000C06366125C
S224FE1680538066F411FC0002C02711FC000401C5600C4A02662012F8C053534166D611FC15
S224FE16A00001C02711FC0000C0276100FF44221F4A3801C54E7511D9C053534166B660DE70
S224FE16C048E76040720143FA07F96100FEB466387402484208380000C063660C538266F4D3
S224FE16E011FC000401C56020422C00036100FECC67160C38000301C5660E0C2C005000016D
S224FE1700660651C9FFC270034CDF02064E7548E760407202103801D6B02C0003674C43F8E7
S224FE172001B032BC030F42290002137801D600036100FE4E66347402484208380000C06379
S224FE1740660C538266F411FC000401C5601C6100FE6A660A197801D600034200600C6100DF
S224FE1760FF60660651C9FFAE70034CDF02064E750000000000000000423801C54A2C0000B5
S224FE17806700010C3F077E0111FC000FC02711FC0000C02711FC0003C02743FA072111FCAD
S224FE17A0000EC0276100FDDA663870064A2C00046702540011C0C02711FC000AC02770FF89
S224FE17C051C8FFFE08380000C06367086100FDEC423801C56100FEEA671C0C38000301C5BB
S224FE17E0670451CFFFA43E1F70014E7570080838000001DB667070044840538066FC197CF7
S224FE1800FFFF000243FA06C06100FD7666D4343CFFFE1038C0510800000756CAFFF6660E56
S224FE182011FC0002C02711FC000401C560B86100FDC066AE103801C1B02C000267086DC406
S224FE18401940000260BE0C000008671A0C00000967100C000010673E0C00000A66267418FC
S224FE1860600674206002742A0C38000201C26614397C0200000619400002194200053E1F13
S224FE188042004E7511FC000901C56000FF5A11FC000B01C54E750C38000101C266E6397C01
S224FE18A001000006742060CE4A2C0000675A4281323C020082EC00064282343801DEC4C1EA
S224FE18C04281122C000284C14241082C000000006604E24AE31111C101D711C201D6B42C48
S224FE18E000016C244842122C00029202C2EC0006B2B801E06F04223801E0520211C201D849
S224FE190031C101DC42004E7511FC000B01C54E75423801DA600611FC000101DA225F49F8E9
S224FE192001C6301F670449F801CE21DF01E021DF01E431DF01DE2F097E034A6C0006660083
S224FE194001146100FE34660000EA4AB801E0670000E211FC0003C0274A3801DA672C083839
S224FE19600001C063670A11FC000C01C5600000C4102C0001E208B03801D66F0811FC000D55
S224FE1980C027600611FC000CC0276100FF1C660000A26100FD7A667443F801B0303C09451B
S224FE19A04A3801DA6602524032C0103801D7E50812C012F801D612F801D712F801D8302CFA
S224FE19C00006E04812C012EC000212EC000512FC00FF43F801B06100FBA86630227801E4EF
S224FE19E04281323801DC143801DA6100FC86661C303C032051C8FFFED3B801E493B801E00D
S224FE1A0082FC0200D37801DE6000FF400838000001DB663A5307671A103801C50C000001C8
S224FE1A206700FF200C00000367080C0000046600FF1A0838000001DB661470074A2C000489
S224FE1A406702540011C0C02711FC000BC027103801C54E750838000101DB6600FEEE700659
S224FE1A604A2C00046702540011C0C02711FC000AC02770044840538066FC6000FECE11EF19
S224FE1A8000040105422F0004427801CC427801D46100EAF246FC270011FC0025C073423829
S224FE1AA001046100E87A41FA026F6100E8966100E86E4267307C04002F082F083F2F000ED6
S224FE1AC06100FE4E6612307C04000C58424F663C0C584F5466364ED06100E844103801C53B
S224FE1AE00C000004673041FA01B96100E8566100E86041FA01CA6100E84A102C00046100C5
S224FE1B00E87A6100E81A205F548F4ED041FA01A16100E83060DC41FA02136100E8266100CB
S224FE1B20E9126100E7FA0C0000516600FF5C41FA02286100E80E60BA2648428042814681B7
S224FE1B4026804A93661C2681B293661C26CBB7C963EE2648B7D3660E588BB7C963F6428063
S224FE1B604ED222006002220B201349FA015D4BFA0006600000842A0B4BFA00066000008628
S224FE1B8049FA01634BFA00066000006E2A004BFA00066000007049FA01524BFA00066000FC
S224FE1BA000582A014BFA00066000005A49FA01B84BFA00066000004249FA015A4BFA0006C8
S224FE1BC06000003670014ED23E3CFFFF08380002C07356CFFFF8671411C6C0717E0E51CFA3
S224FE1BE0FFFE08380002C07366024ED608780003C06551CFFFFE60F41C1C67064DFAFFFAE6
S224FE1C0060C64ED57807E99D7C0FCC050C060009630406060007060600304DFA000460A8F3
S224FE1C2051CCFFE44ED5044A0452045A80020462046A049A045A045A800B047280060482BF
S224FE1C40048A800E047A0492800F04720000070D0A455843455054494F4E3A202000070DF1
S224FE1C600A204E4F204D656D6F72792061743A20000D0A4C6F616420446F6E6500070D0A57
S224FE1C80426164204C6F616420436861726163746572000742616420436865636B73756D8C
S224FE1CA000074472697665204572726F722000074E6F7420424F4F54204469736B00206F10
S224FE1CC06E206472697665200007424144204D656D6F7279206174200052414D2053697A87
S224FE1CE065203D2000206973200020696E7374656164206F6620000D0A53414745204949DD
S224FE1D000020537461727475702054657374205B312E325D0D0A00426F6F74696E67206615
S224FE1D20726F6D20466C6F7070790050757420696E20424F4F54206469736B20616E6420F6
S224FE1D4070726573732061206B6579202851202D207175697473290007426F6F74204162A6
S224FE1D606F72746564002028546573742041626F727465642900202046696C6C696E67202B
S224FE1D806D656D6F72792E2E2E0020204C6F6164696E672E2E2E00202057726974696E6771
S224FE1DA02E2E2E0020204D6F76696E67206D656D6F72792E2E2E000750524F4D20312042AB
S224FE1DC061640D0A000750524F4D2032204261640D0A00427970617373656420496E697460
S224FE1DE00D0A004C6F6F7065642054657374730D0A0052414D207772697465206C6F6F7017
S224FE1E000D0A0000001F0027002B003300470052005C006A007A008F204572726F722061F1
S224FE1E20742000556E6B6E6F776E00427573004164647265737300496C6C6567616C204908
S224FE1E406E737472756374696F6E0041726974686D657469630050726976696C6567650075
S224FE1E605265736572766564205452415000556E61737369676E6564205452415000556E9D
S224FE1E8061737369676E656420496E746572727570740052414D20506172697479004675D0
S224FE1EA06E6374696F6E3A200020204163636573733A20002020496E73743A20000303D13F
S224FE1EC0070207000108024A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
S224FE1EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
S224FE1F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
S224FE1F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
S224FE1F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
S224FE1F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
S224FE1F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
S224FE1FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
S224FE1FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
S224FE1FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
S804FE0000FD

514
SAGE/FILES/sii.hex Normal file
View file

@ -0,0 +1,514 @@
S00A00007369692E68657847
S224FE00000000040000FE0044600004F2600004E66000095E60000448600003F2600003CA02
S224FE0020600003F8600003FE600029A2600029A460000334E4A70201600002F66000340098
S224FE0040600034FA4E704FF8040011FC0092C02711FC0038C02511FC0092C06711FC003152
S224FE0060C065700072FF343C42D741F8C0FE3080308151CAFFFA43F8000045F87FFE343C1D
S224FE0080344230113010301251CAFFF8343C06C541F8C00172084A10D0FC001051C9FFF81C
S224FE00A051CAFFEE43FA0006600002C049FA2D054BFA000660002BFE41FA00362278000874
S224FE00C021C80008B1F80008662E11FC0090C58711FC0090C50711FC0000C58311FC00CD66
S224FE00E0C50311FC0000C58511FC0005C50560044FF8040021C900081038C0216B64E6087B
S224FE010002400006303B00064EFB000200180024001800084238010449FA2D744BFA08527A
S224FE012060002B9249FA2D784BFA003860002B8649FA2D7B4BFA000660002B7A74FF720009
S224FE014070001038C023460008000002670272FFE308024000064840204030C151CAFFFCB5
S224FE016060DA41FAFE9C343C1FFF42004201D018D21851CAFFFA4A00671449FA2CF64BFA05
S224FE0180000660002B304A38C0216A0001004A01671449FA2CEC4BFA000660002B184A383C
S224FE01A0C0216A0000E811FC0001C067307C000072014841323CFFFE224145FA00066000B9
S224FE01C02A34664647FA000C21CB000808F80002C5034FF8040047FA002421CB00087202EF
S224FE01E04841D3C1303CA5A53280B051660E46403280B05166064640D3C160EC4FF80400AC
S224FE020093C145FA0006600029EC67084A38C0216A00007A303C00BF41F80100429851C8BF
S224FE0220FFFC548921C901004E6121C9014A21C9014243FA000C21C9000808B80002C50322
S224FE02404FF804006100041611FC0000C0674A38C0216B1611FC0007C06770FF51C8FFFEFD
S224FE026011FC0006C0676000FEFA6100017C41FA2B256100019830380100ED48610002166F
S224FE0280704B610001DA6100016060044E7227007228740208380006C0216702725011C222
S224FE02A001C611C101C7423801CA11C201CE11C101CF11FC000101D27206610000F8423825
S224FE02C001BA2278000841FA002A21C8000811FC00AAC58311FC0005C5050C3800AAC58357
S224FE02E0661011FC0000C58350F801BA31FC023001F04FF8040021C900081038C021C07C3B
S224FE03000030670CB07C00206724B07C0010672621F80100014A21F80100014231FC270081
S224FE0320014E41FA004221C801466000064442676100280860DA4A3801BA67D420380100CF
S224FE03404840720C92406F12C2FC000A5341303C6F9A51C8FFFE51C9FFF6426770012F0002
S224FE03606100332260AA4E4F60FC41F8C0734200108011FC0076C007E01810801238C02186
S224FE0380E0181080706E080100036702707E10BC00400241000711FB1014C003108011FCAB
S224FE03A00000C003E01810BC00254ED1028040201008040241F8C0334240108011FC00B66E
S224FE03C0C007E018108011FB10E4C005E018108011C0C005E01810BC0040E01810BC004ED2
S224FE03E0E01810BC00274E752F00700D6170700A616C420061686166616461626160201F2E
S224FE04004E752F0070206156201F4E753F0010186704614A60F8301F4E75E9186126E9182E
S224FE042061224E752F017203E958611851C9FFFA221F4E752F017207E998610851C9FFFA57
S224FE0440221F4E753F000200000FB03C0009630406000007060000306104301F4E754A38AD
S224FE04600104662C3F01323CFFFF08380002C07356C9FFF8670811C0C071321F4E7548E7F7
S224FE0480C0C043FA00066000FEE24CDF030360D64E4A4E7548E7F000720032007400343CED
S224FE04A02710420382C266044A0367061001619450C34241484184FC000A66E84CDF000F1E
S224FE04C04E754A38010466282F011238C0730801000167F61038C071020100386604221FCE
S224FE04E04E7511FC0035C07370076100FF7260DA4E494E7508380001C0734E7561C4088000
S224FE050000070C0000616D0A0C00007A6E04088000054E7521C001067002604E21C00106B5
S224FE05207004604621C001067006603E21C001067008603621C00106700A602E21C00106D4
S224FE0540700C602621C00106700E601E21C001067010601621C001067012600E21C0010614
S224FE05607014600621C00106701648F87FFE010A4E6821C8014A2A007016BA806270BA3CBC
S224FE058000046206381F261F341F31DF014E21DF014621CF01424FF804000C05001467004D
S224FE05A0199A6E0018B80C050012661E11FC0001C06711FC0000C0674A3801BA670C08F887
S224FE05C00002C50308B80002C50370FFE01851C8FFFC46FC270011FC0038C02508B80006F0
S224FE05E001504238010443FA000A6000FD7E428560A849FA27164BFA0006600026B849FAEB
S224FE06002954D8F450004BFA000460EE49FA295A4BFA000460E420380146610017F66100E6
S224FE0620FDC80C0500046200034841FA29C26100FDDC30046100FDEE41FA29BF6100FDCE01
S224FE064020036100FDF041FA29BC6100FDC030026100FDD26100FD926000031641F80008DC
S224FE066043FA268045FAF99A4280301967186B06D08A20C060F2424112003019D08A20C023
S224FE068051C9FFFC60E24E75225F02800000000FD080D089C1893251D3C04ED148E780B0A4
S224FE06A02478000847FA001421CB0008101121CA00084CDF0D01B0004E75508F321F46C153
S224FE06C041FA26586100FD46588F20096100174421CA00084CDF0D01000000014E750838BE
S224FE06E00001C0734E752F00703A6100FD72201F6100FD104E752F00702C6100FD62201F1D
S224FE07004E752F0070076100FD56201F4E75C03C007F0C0000206D060C00007E6D02702E06
S224FE07204E752F092F01224842816100FDD00C00001B6700006E0C000012670000680C003B
S224FE0740000D674A0C000008661AB3C867DC6100FD0E6100FCAE6100FD0651C9FFF25389C4
S224FE0760528260C40C00007F6614B3C867BC61585389528210116100FCE6544160AC611AF2
S224FE0780428153826B0812C06100FCD4609C610A421912C0221F225F4E758281673C4281C6
S224FE07A0602C224842812F0870236100FCB26100FC38B3C86700000C10186100FCA2B3C87F
S224FE07C066F6205F6000FF648281660E72013F00103C005C6100FC88301F4E7542801018C6
S224FE07E08000660253884E7561F28000670A0C00002067040C00002C4E7561E067080C00DE
S224FE0800002067F653884E7561D2244942411219B011568957C9FFFA660001481021E1589A
S224FE08201021D4C04ED248E7180042817801E89C61B667540C00002F660E383C33334844E2
S224FE0840383C333461A26740040000306D380C0000096F144A04662E040000070C00000A9C
S224FE08606D240C00000F6E1E26014A046708E799E39BD2836002E999B684640AD280848222
S224FE088067C2B48164BE72FFC1414CDF00184E752F036100FF66428395CA6100FF4C67002D
S224FE08A000480C00002367360C0000246708347801525388602A6100FF306700002C0400F7
S224FE08C0003065240C000003641E244093C96100FF18670000180C00002B660C6002528334
S224FE08E042826100FF42670257832240D5CAD5CAD4FC0154D3D2201FC14380804E752F02AB
S224FE090042826100FEF6670000520C000027671C0C00002E674624016100FF0C6B06241F20
S224FE092092814E75241F428153814E756100FEAE6100FEAA670000200C0000276712E19A7D
S224FE09404A0266E0D480828167E6B28264E260D46100FE9666CEC14260C47001241F22008A
S224FE09604E756100FA9E703F6100FAF46100FD944FF8040042B801546100FA6E083800061F
S224FE098001506700000870546100FAD436380152670C70246100FAC810036100FAA8703EF2
S224FE09A06100FABC742841F801886100FD7643FA1A686100FE5460B843FA1A8C6000FE4AD6
S224FE09C06100FE382838017E387801821010670E6100FEBE668C2809284A31CA0182610045
S224FE09E0FE1A327C01001010670A6100FEA46B00FF726704D3C45389528921C9017E2A0968
S224FE0A00611C6718280B6100FCD667F46100FAEE0C00001367F60C00000366E44E756100D4
S224FE0A20F9C820046100FA0EB8FC0154670C6100F9D2200490946100F9FC6100FCAA760F93
S224FE0A402644C7496100FC56C7496600FF16101B6100F9C808030000660000066100F9A419
S224FE0A60BA8B57CBFFDE6100F99A760F2644101B6100FC9C6100F9E8BA8B57CBFFF24E75CB
S224FE0A8043F80154323C20247402601443F80126323C2041600843F80106323C20447407FF
S224FE0AA06100FD3A671A903C00306B00FEB678001800B8026E00FEAC61226100F92C4E75D1
S224FE0AC04284611852846100F93A0C04000466046100F9306130B8026DEA4E756100F90A99
S224FE0AE042833001E0880C000020670000066100F96E10016100F968868366061004610077
S224FE0B00F9446100FBE22004E5800280000000FF4A836A42303100006100F90A0C4153521D
S224FE0B20663C48E7704036006100F8D870286100F92E428243FA18D21419670E1019E57B94
S224FE0B40650270206100F91860EE4CDF020E70296100F90C6008203100006100F8D84E75F4
S224FE0B606100FC7A6600FDFC6100FF226100FF28611861086148610461344E756100F8840D
S224FE0B806100F8804E756000F86061FA103C00506100F8CC103C00436100F8C46100FB4892
S224FE0BA020380146307801526000126861D876FF43F8014E223C00005352600E61C843F8B1
S224FE0BC0014A223C00005553760142846100FF144E757C0060000C2C700072104A10670A7C
S224FE0BE06100FC446B00FD7C12006100000E5200B0016DF66100F7F24E756100F7EC41FAFA
S224FE0C0000206100F8086100F83C41FA001B3438017C0102670441FA001B6100F7F04E75AD
S224FE0C205452415020230020204E6F2074726163652000202054726163652020202000003C
S224FE0C4043FA18A26000FBC26100FCB46600FD142A006100FCAA6600FD0A2800D085610079
S224FE0C60F7882200103C002B614822059284103C002D613E2205C2C4103C002A61344A4415
S224FE0C806746220582C4103C002F61186132103C00726100F7CA103C00656100F7C2103CB9
S224FE0CA0006D48416100F7B86100FA3C30016000F7746100F7AA6100FA2E20016100F7761E
S224FE0CC06100F7406000F73C4E757C106100FB2C2838017E38780182101067106100FBB258
S224FE0CE06600FC802809284A31CA01826100FB0C327C00141010670C7CFF6100FB946B005B
S224FE0D00FC6267062C096B00FC5A52892A092C446100F6D6200E6100F71CB8FC0154670C46
S224FE0D206100F6E0200E90946100F70A6100F9B848E7060061304CDF006021CE017E4A8624
S224FE0D406B065386671E2A0EBA8E650000186100F98E67BC6100F7A60C00001367F60C0033
S224FE0D60000366AC4E75300EE2086500FBF67C07610006F03E00E9586100F90E0020010038
S224FE0D8001080104014003880428046E0512060606CC053A05A60606065206CC08070008AC
S224FE0DA0664E43FA176C3207E049E249610006F659016F5E0401001067585801660642458B
S224FE0DC0611C60063A07610006C4610006FC6100070216076100F920610007364E75428535
S224FE0DE043FA171E3207EC5902410003600006B63007020000380C00000867367042610069
S224FE0E0006AE61DA610006C23607EC5B6100072860C030070200003F0C00003C66A64282F3
S224FE0E20263A084C080700066704263A0846600000F2203A082A610006767050610006707B
S224FE0E403A07E35D08C500066100064E6100067A08070007670A61126100F89C61144E757E
S224FE0E6061106100F89261024E753607EC5B600006C6360708C30005600006964285600607
S224FE0E807A4060027AFF203A07D6610006223007EC5802000007530066067041610006108F
S224FE0EA0610005F6610006223607610006646100F8463607EC5B610006644E75080700087A
S224FE0EC0660002043007EF580240000732006100F7B8001000320014001C007C011800B2E1
S224FE0EE001527401600A263A0786428260064282263A0780283A07683007020000C00C0025
S224FE0F0000C0671843FA16366100059A3A076100057C610005B4610005F64E752004610025
S224FE0F20058E7A40610005A228034A026614610005DE4A84670A6100F7BE200461000570D5
S224FE0F404E7561F66100F7B0610005C44E753207E65902410007080700076624203A0718A4
S224FE0F6008070006670C203A07124A016604203A070E6100053A61000550610005924E753E
S224FE0F804A016756203A06D861000524704D3A07E35D08C5000661000516610004FC610035
S224FE0FA005287A40610004BC31C001880807000A661E6100000C6100F73E610005524E7591
S224FE0FC070236100F49A303801886100F4584E7561E86100F72261E84E75203A06AA080743
S224FE0FE00006678E203A069C60880C0700FC6612203A0698610004B8203A0694610004B06A
S224FE10004E753A07024500C00C4500C0670A3005E2588A406000FEEE283A06784282428352
S224FE10206000FED608070007660000983207E6590201000714010C01000667520C010003F2
S224FE10406F14263A065E024200010247000F004700C86000FEA043FA14FC61000448610041
S224FE10600468E20A660E70236100F3F430076100F3D44E753607E75B610004C008070003EE
S224FE1080660A6100F6727A40610004484E75320702410007340143FA14CC610004080C029A
S224FE10A00002660A610004227A406100042670544A02670870560C02000666046100F3A038
S224FE10C04E754280600270023207EC59C27C0001D2407A4043FA14AE610003CA610003EAB0
S224FE10E06100042C0807000867186100F60A3607EF5B70200807000667027028B1436100E3
S224FE110004104E753207020100C00C0100C0673E203A0588080700086704203A05826100DC
S224FE1120038E3A07610003666100039E70236100F32E3007EF58020000074A006602700848
S224FE11406100F3026100F5B0610003C44E7570533807020400380C040008660808870003ED
S224FE1160303C4442611C610003A60C04000866106100F5847A40610003603440610003FA3B
S224FE11804E7543FA1440610003263207EE5902810000001ED3C142803011610003126100DF
S224FE11A003284E757A40320702410F000C410100670A704243FA13EE61CC600C203A04D87B
S224FE11C0610002EC6100030230074A0067106100F24AE158E040548E6108558E4E75610017
S224FE11E002F83440610003924E750807000866000258203A046A610002B67051610002B039
S224FE1200610002C670236100F25610076100F20C6100F4E43607EC5B6100031C4E753A07AF
S224FE122043FA13C2612208070008670C61106100F4C6610002DA4E7561F86100F4BA36075B
S224FE1240EC5B610002F24E753207E95902410007610002524A456704610002326100026A56
S224FE12604E75428560023A0743FA139A61DA3607E75B61086100F4803607EC5B08070003C6
S224FE12806606610002B24E75610002C04E753007024001F00C40010067C8EC4872045740FA
S224FE12A0670859406600FF787205088700068E7C41006000FE1E3007EC580240000755401A
S224FE12C06F00FF5C43FA133E7A4053406706E35D594066166100FF72610002346100F418CE
S224FE12E03607EC5B610002544E75044710003007024000380C4000086600FF24203A03A8FF
S224FE1300610001AC3A0761000184610001BC3607E75B61086100F3E03607EC5B610002264E
S224FE13204E753007024001F878000C400140671078030C400148670878020C4001886624A1
S224FE1340203A0368610001686100017E3607EC5B61086100F3A23607E75BE21C650001DC79
S224FE1360600001D4E8480C0000106700FEF67206E44857406700FF347207594067F66000EA
S224FE1380FE9E3007024000C00C4000C067123007024001300C4001006700FECC6000FE80EA
S224FE13A03A07E25D43FA12563207E55902410001610000F2610000E26100010E6100015092
S224FE13C06100F3343607EC5B610001704E7532073A07024500C00C4500C06744E65961503C
S224FE13E0610000AA610000E2360702430E00080700056708EC5B6100013E60167023610038
S224FE1400F05E3003EF580200000F660270086100F0346100F2E23607E75B6100011A4E7598
S224FE1420EF59610C4285610000A0610000E24E7502410003340702420100EC5A824243FA19
S224FE144011DC610000604E75702E61000062203A02126100005A6100007030076100EFC670
S224FE14604E752F09224E6100F2346600F4F6301E225F4E752F09224E6100F2226600F4E43A
S224FE148054896100F218201E225F4E75024500C00C05008066027AC03205EC5902010003C3
S224FE14A043FA108AE519024100FF203110002F017203E1984A00670000086100EFA253068F
S224FE14C051C9FFF0221F4E756100EF3851CEFFFA4E7570236100EF883205EC59C27C000371
S224FE14E0B23C000267206100FF7A53016C066100EF2A4E756100EF2E53016D086100FF648A
S224FE15006100EF224E75703F6100EF544E7536071003E60802000007E70B86001003024069
S224FE152000076100F164001000140018001E00240076008000C67244601472416010223A08
S224FE15400112600A223A01106004223A010E7403E1991001671C6100EF060C000044670637
S224FE15600C000041660C3003E618020000076100EED451CAFFDC4E75705B6100EEE2D5CEF4
S224FE1580200A558030780152D1C8D1C890A801546100EEA2705D6100EEC64E756100FEC4D6
S224FE15A06100EE8260986100FEBA38006100EE6C70286100EEAA61826100F13C3604EF5BCD
S224FE15C00804000F66066100FF6E60046100FF6C702E6100EE8A70570804000B6702704C09
S224FE15E06100EE7C70296100EE764E75E61BC63C000710036100F0920012001C0026003E6A
S224FE160000540010001000104E756100FE566100EE144E756100FE5E6100EE1A4E7561005B
S224FE1620FE4234406100EDFE223A003C6100FF206100FF464E756100FE2A38006100EDDC3B
S224FE1640203A00286100FE686000FF6E6100FE844E75284129002841292B2D2841294D4F21
S224FE16605645574F5244285043292850430043435200535200004E424344504541005357DD
S224FE168041504558544C45585457494C4C4547414C005441530042535200414444515355A6
S224FE16A0425155535000434D504D4558470043FA0DB56000F1546100F1D86600F2A660045B
S224FE16C06100F0402809284A2A0454856100F3506100F01441F80188243C00000028610018
S224FE16E0F042428110106716223C0000FFFF6100F20E6BCC6E0A13400001E08012805489C6
S224FE17000C01002E66BE4E7543F80154323C202474037A01601643F80126323C2041600861
S224FE172043F80106323C2044740842856100F0AE671A903C00306B00F22AB0056B00F22416
S224FE1740B0026C00F21E4282610E4E75200561085280B0026DF84E7542832F023A012800CF
S224FE17602C00E5864A82660E6100F0904A10662260046100EF8E32056100EC6E6100F364E0
S224FE17806100EF64742841F801886100EF961010672042816100F1686BD8660000160286E3
S224FE17A0000000FF86836A063380600060042380600032051004241F4E756100F02066000C
S224FE17C0F1A26100FF526100FF586106611E610E4E7543F80146323C50436000001843F8BB
S224FE17E0014E323C535276FF6000000C43F8014A323C55537601428242806100FF5E4E7589
S224FE18007CFF7A0142806100EFD467144486903C00306B00F14EB03C00016E00F1463A0032
S224FE1820360060046100EEDC3643D7CB284BD7CB4A866B0A675A6100EFC24A106614616AF9
S224FE18406100EEA4742841F801886100EED66100EFAA101067320C00002E660607B80150A6
S224FE186060266100F02C6BBC6100EF90243C0000FFFF6100EFB26BAC426C017239400176D3
S224FE188007F80150274901605243B6456F9A4E75611860F4427265616B706F696E742000CC
S224FE18A0496E61637469766500006100EB3C41FAFFE46100EB5810036100EB8A6100EE2848
S224FE18C007380150660A41FAFFD86100EB404E75202B01606100EB5E6100EB2870286100E1
S224FE18E0EB7E302C01766100EB3C6100EE0A302C01726100EB3070296100EB644E757600FB
S224FE190078104A10671C6100EF1E6B00F056160018006100EEE60C00005467460C00004E76
S224FE192067386100EAC441FA004C6100EAE010036100F2C86100EDB0742841F80188610059
S224FE1940EDE26100EEB667240C00005467140C00004E67066100EDAC60C83238017C0781F2
S224FE196060063238017C07C131C1017C5203B6046DBC4E7528542972616365206F7220285C
S224FE19804E296F2074726163650043FA0AF86000EE78243C000000FF616C6600EFC61A00C9
S224FE19A0E1401005600C243C0000FFFF61586600EFB23A0048403005600842826148660032
S224FE19C0EFA241FA146D6100EA4461000942E19812C0538466F821CA00084E7548E7F00027
S224FE19E06100EEAE661A28096100EEA62449C9896B0E6E06988952846004D5C9538A4280FD
S224FE1A004CDF000F4E7561D4660622026100EEF04E7561F266142C0098876D00EF4670FFD6
S224FE1A204A10670A22026100EED66600EF3641FA14E96100E9D8610008D64E7543FA0AB4AD
S224FE1A406000EDC6243C000000FF7E0161C41219C200B206670453846CF46100009660F6D9
S224FE1A60243C0000FFFF7E0261A81219E1991211C240B246670453846CF06100007660F6EF
S224FE1A8042827E04618C2649548B1219E1991211E199121BE1991213C280B28667045384F8
S224FE1AA06CE86100004E60F66100FF326600EEB448E708606100FF266600EEA82A492C0474
S224FE1AC04CDF0610C34D41FA14516100E9406100083E9C846518284952892E04264D121C25
S224FE1AE0B21B6606538766F6610853866CE861024E7148E7FE7E663E41FA142E6100E90E98
S224FE1B00538920096100030C6100EBDC7203E198101951C9FFFA6100E91C41FA14186100CD
S224FE1B20E8EC6100E9D80C00004366126100E9304CDF7E7F4E7541FA13D06100E8D04CDF1E
S224FE1B407E7F21CA00086000EE286100E8B66100E8B243FA093A6000ECB043FA093C6000C4
S224FE1B60ECA86100ED2C6600EDFA20096100E8C66100EB7410116100E8A24E756100ED12E0
S224FE1B806600EDE03C09080600006600EDD620096100E8A26100EB5030116100E8884E750E
S224FE1BA043FA08FD6000EC626100ECE66600EDB4223C000000FF6100ED466600EDA612807C
S224FE1BC04E756100ECCC6600ED9A3C09080600006600ED90223C0000FFFF6100ED226600D1
S224FE1BE0ED8232804E756100EC1274076100EC386B00ED7022006000E7BC43FA08AA600063
S224FE1C00EC086100006443FA07B654894A516700ED523014C059B05966F0D8D121CC016835
S224FE1C2008F80002015008F800040150600261387401610001BA426A017251CAFFF66002DC
S224FE1C40612608B80005015008F80006015008F8000701501038015002000007660608B867
S224FE1C6000060150600001506100EB901010670C6100EC1E6600ECEC21C901466106610048
S224FE1C80E7684E752C380146284608060000671241FA001C6100E77620066100017660001C
S224FE1CA0ECD0224C6100E9F66600ECB84E75496C6C6567616C2070726F6772616D20737411
S224FE1CC061727420616464726573733A20006100E71843FA07DC6000EB30083800060150C8
S224FE1CE0670461A0604E4E7508F8000501506040619208B8000301500C100049660808F834
S224FE1D000003015052887005083800050150660270104A10670E747F6100EAE06100EB085E
S224FE1D206B00EC406100E6C2600C08B8000501506100FF36700111C0015108F800060150FD
S224FE1D4008B80007015030140240FFF00C404E406664301C0240000F3C38017C41FA002C5A
S224FE1D600106661C21CC016808F80007015008F80002015008B800040150673A41FA0021C4
S224FE1D806100E68A6100E662602C2A2A2A2054726163696E672054524150202A2A2A002AB5
S224FE1DA02A2A204753207465726D696E61746564202A2A2A0000287801463C38014E08383D
S224FE1DC00006015066060886000F600408C6000F2078014A4E602E7801422F0C3F064CF821
S224FE1DE07FFF01064E7308B8000601504E7542803242D3C92449D3C905380150670E226957
S224FE1E0001606100E8986600000652804E7553804E756100E62030780152D0C8D0C84A7892
S224FE1E200152672E6100E5DC2F0070286100E63070246100E62A303801526100E6086100E7
S224FE1E40E8A6201F90A801546100E5EA70296100E60E4E7554726163653A200008380006B5
S224FE1E6001506700FF52083800070150672608B80006015074006100FF766B00EAE6670826
S224FE1E803551016C32BC4E4F52420C42000366E66000FF2441FAFFBE2038014621C0017E16
S224FE1EA06100E56A28406100FF6AD0FC015431C801826100E832224C6100E7E266143011D2
S224FE1EC06100E5626100E53C6100E5382C496100EE96083800050150670A41F801884210E2
S224FE1EE06100EC7E533801516F1E083800030150671A6100E7EA67146100E6020C00001380
S224FE1F0067F60C00000366046000EA666100E4DA6000FE280D0A556E657870656374656467
S224FE1F2020627265616B20706F696E743A2000000D0A427265616B3A200042854286283890
S224FE1F4001465584760041FAFFCC74026100FEA06F32B3C4661E41FAFFD876020C02000237
S224FE1F6067123A2A01723C2A0176BC4567065245354501720C514E4F670605B80150600466
S224FE1F8032AA016C51CAFFC60838000201506728B8B80168662208B80002015008B80004BB
S224FE1FA00150661421C4014608F80006015008B8000701506000FEA620380146908321C021
S224FE1FC00146BC456600FC824A436600FED028440C544E4F6600FEC620046000FEC043FAFF
S224FE1FE004E46000E82411FC000101BB6004423801BB41FA0E516100E41460764285740121
S224FE20006100E8246B00E95C3C00243C0000FFFF6100E8146B00E94C3F006100E8746600A7
S224FE2020E9422F0942826100E7FE6B00E9362F003F064A85670E41FA0E1A6100E3D0610016
S224FE20400992600C41FA0DFF6100E3C26100097E6700000E41FA000C6100E3B26100E3BC8F
S224FE20604E750D0A4469736B206572726F723A20000061740C000051670000C00C0000539C
S224FE208066F0420561621E00610000BC1C0153064281610000B2610000AE26410C0700309D
S224FE20A0660E4A0667066100009E60F6617460C20C0700326614220B6100008C26414A0610
S224FE20C067EA6100008216C160F40C07003167EE0C07003966644A066660614641FA0C4F9C
S224FE20E06100E32A6000E88A4A3801BB672408380001C033670A1038C031088000074E75A4
S224FE21006100E3F267E26100E3F40C00005166D84E756100E3AE0C00000D6700E2CC600027
S224FE2120E33E6122460566024E75588F41FA0C216100E2DA6000E83A508F41FA0BFD610011
S224FE2140E2CC6000E82C61086106DA0153064E7561960C0000306DE00C0000396E0A040052
S224FE21600030E989D2004E750C0000416DCA0C0000466EC45F0060E643FA03436000E68A25
S224FE21807A016000FE7A6000E7E843FA03426000E678202053797374656D207265696E697E
S224FE21A07469616C697A696E672E2E2E2E0046FC270011FC0025C0734238010441FAFFD43E
S224FE21C06100E24A70FF51C8FFFE6000DE784280428710100C00005266063E3C010052886A
S224FE21E01010670A74016100E63E6B00E77680473F00610009464E754A3801BA6700E76421
S224FE2200428042877C0110100C00005266063E3C010052881010675C0C00002067140400E6
S224FE222000306D00E73E0C0000036E00E7368E0052886100E5C64A00673A0C00002366004B
S224FE2240001652884A10672C740F6100E5DA6B00E7123C00601E740743F801F62C09429128
S224FE226042A90004422900086100E572670612C051CAFFF63F072F066100140A4E754E7572
S224FE228074186100E16451CAFFFA4E7543FAE2D621C9002443FAE2C621C900BC4E7542801F
S224FE22A01010670A74026100E57E6B00E6B631C00152E540D07C015431C001824E756100A7
S224FE22C0E5D06600E69E28096100E5C66B00E694C98966049889600253846500E6862649E4
S224FE22E06100E5AE6600E67C41FA0B756100E11E7201B7C96406D3C4D7C472FF61101293EE
S224FE2300D3C1D7C153846CF621CA00084E752478000849FA000821CC00084E7541FA09FCB8
S224FE23206100E0EA548F201F6100FAE821CA00086000E63E43FA01B56000E4CE3F3C000112
S224FE23406002426774016100E4DE6B00E6163F00243C0000FFFF6100E4CE6B00E6063F002A
S224FE2360427801CC427801D411FC000101DB3F172F3C000004002F3C000010003F2F000CA0
S224FE23804A6F001067066100064A60046100063E662A702E6100E0C808F8000101DB6100D5
S224FE23A0E15467CA6100E11C11FC0007C02711FC0009C027423801DB5C8F4E75705860D45E
S224FE23C0F0FF60000004F00060000002F0F850C80004FFB84E900002FFB84EA80004FFB852
S224FE23E04EB00004FFBF4EB80004FFBF4EB90006FFBF4EBA0004FFBF4EBB0004FFF04E4033
S224FE24000002000000000000015402530958014E015A0156014300000E44A0E55396F2466F
S224FE242072F52486FE4DA6FE5032F754B6F847E2F75760FD4CC6FB00C2F84972FD4128E87A
S224FE2440451CFF5824F6094D7AE5521AE74450E64146E65044E75366E75576E7243AE64265
S224FE24608CE75492E7094D51F25255F344BBF241B1F2506DF35379F35587F324A3F2429B3D
S224FE2480F35499F402420EF55722F54C36F50249CCF64F12F75358F70142CAF657E4F601FD
S224FE24A04209F75723F7024F88F7439AF7535CF703427AF84536F95238F84E40F80141C9DE
S224FE24C0FC46C3FC024122FB542AFB4638FB064600FD482AFD47B0FD53E0FC568EE143B211
S224FE24E0FD54BEFD0144E6E75264E7015257FE5751FE034252F5576EF54C8EF54DB6F500C3
S224FE25005453540043484700434C5200534554004F524900414E44495355424941444449D3
S224FE252042000000454F5249434D50492E4200002E5700002E3F00002E4C00004E454758F0
S224FE2540434C52004E4547004E4F5400000000005453540054524150545241504C494E4B35
S224FE2560554E4C4B524553454E4F500053544F5052544500344537345254530054524150BD
S224FE2580525452004A5352004A4D500043484B004C45410044495655444956534D554C5511
S224FE25A04D554C535241460048494C53434343534E45455156435653504C4D4947454C54E9
S224FE25C047544C455400460048494C53434343534E45455156435653504C4D4947454C541D
S224FE25E047544C454F52000053554200454F5200434D5000414E4400414444005355424194
S224FE260041444441534243445355425800000000434D50414142434441444458415352001D
S224FE26204C535200524F5852524F520041534C004C534C00524F584C524F4C0048E760409C
S224FE26401219143C00AD1038C0510800000756CAFFF6671A08000006661411D9C05374094F
S224FE266051CAFFFE530166DA4CDF02064E7511FC000101C560F248E7604043FA099861BCC5
S224FE26806624720243F801C36174661A123801C3020100C0670C0801000667047203600250
S224FE26A0720211C101C54CDF02064E7548E76040720743F801BC42116144663C123801BC34
S224FE26C0020100C0672E0801000667267205103801BDE208651E7206E40865187207E408D3
S224FE26E065127208E208650C7209E4086506720A6002720211C101C54CDF02064E75343C69
S224FE270010FE1038C0510800000756CAFFF6671608000006671012F8C053740951CAFFFE77
S224FE2720530166DA4E7511FC000101C54E752F017002484008380000C0636612538066F476
S224FE274011FC0002C02711FC000401C5600C4A02662012F8C053534166D611FC0001C02789
S224FE276011FC0000C0276100FF44221F4A3801C54E7511D9C053534166B660DE48E76040B8
S224FE2780720143FA088D6100FEB466387402484208380000C063660C538266F411FC00042B
S224FE27A001C56020422C00036100FECC67160C38000301C5660E0C2C00500001660651C927
S224FE27C0FFC270034CDF02064E7548E760407202103801D6B02C0003674C43F801B032BCFE
S224FE27E0030F42290002137801D600036100FE4E66347402484208380000C063660C538201
S224FE280066F411FC000401C5601C6100FE6A660A197801D600034200600C6100FF6066068A
S224FE282051C9FFAE70034CDF02064E750000000000000000423801C54A2C00006700010C3B
S224FE28403F077E0111FC000FC02711FC0000C02711FC0003C02743FA07B511FC000EC027C7
S224FE28606100FDDA663870064A2C00046702540011C0C02711FC000AC02770FF51C8FFFE97
S224FE288008380000C06367086100FDEC423801C56100FEEA671C0C38000301C5670451CF75
S224FE28A0FFA43E1F70014E7570080838000001DB667070044840538066FC197CFFFF0002B1
S224FE28C043FA07546100FD7666D4343CFFFE1038C0510800000756CAFFF6660E11FC0002E2
S224FE28E0C02711FC000401C560B86100FDC066AE103801C1B02C000267086DC419400002EA
S224FE290060BE0C000008671A0C00000967100C000010673E0C00000A66267418600674208C
S224FE29206002742A0C38000201C26614397C0200000619400002194200053E1F42004E7537
S224FE294011FC000901C56000FF5A11FC000B01C54E750C38000101C266E6397C010000062E
S224FE2960742060CE4A2C0000675A4281323C020082EC00064282343801DEC4C14281122C1F
S224FE2980000284C14241082C000000006604E24AE31111C101D711C201D6B42C00016C24E7
S224FE29A04842122C00029202C2EC0006B2B801E06F04223801E0520211C201D831C101DC3A
S224FE29C042004E7511FC000B01C54E75423801DA600611FC000101DA225F49F801C6301FD2
S224FE29E0670449F801CE21DF01E021DF01E431DF01DE2F097E034A6C000666000114610053
S224FE2A00FE34660000EA4AB801E0670000E211FC0003C0274A3801DA672C08380001C063BA
S224FE2A20670A11FC000C01C5600000C4102C0001E208B03801D66F0811FC000DC02760065B
S224FE2A4011FC000CC0276100FF1C660000A26100FD7A667443F801B0303C09454A3801DA3A
S224FE2A606602524032C0103801D7E50812C012F801D612F801D712F801D8302C0006E04858
S224FE2A8012C012EC000212EC000512FC00FF43F801B06100FBA86630227801E4428132381F
S224FE2AA001DC143801DA6100FC86661C303C032051C8FFFED3B801E493B801E082FC0200E9
S224FE2AC0D37801DE6000FF400838000001DB663A5307671A103801C50C0000016700FF20F2
S224FE2AE00C00000367080C0000046600FF1A0838000001DB661470074A2C00046702540082
S224FE2B0011C0C02711FC000BC027103801C54E750838000101DB6600FEEE70064A2C0004CB
S224FE2B206702540011C0C02711FC000AC02770044840538066FC6000FECE11EF00040105B8
S224FE2B40422F0004427801CC427801D46100DB0E46FC270011FC0025C073423801046100EF
S224FE2B60D88841FA026E6100D8A46100D87C4267307C04002F082F083F2F000E6100FE4EC5
S224FE2B806612307C04000C58424F663C0C584F5466364ED06100D852103801C50C00000409
S224FE2BA0673041FA01B96100D8646100D86E41FA01CA6100D858102C00046100D888610049
S224FE2BC0D828205F548F4ED041FA01A16100D83E60DC41FA02126100D8346100D92061006B
S224FE2BE0D8080C0000516600FF5C41FA02276100D81C60BA264842804281468126804A93C4
S224FE2C00661C2681B293661C26CBB7C963EE2648B7D3660E588BB7C963F642804ED22200D3
S224FE2C206002220B201349FA015D4BFA0006600000842A0B4BFA00066000008649FA0163F2
S224FE2C404BFA00066000006E2A004BFA00066000007049FA01524BFA0006600000582A014F
S224FE2C604BFA00066000005A49FA01B74BFA00066000004249FA01594BFA000660000036E6
S224FE2C8070014ED23E3CFFFF08380002C07356CFFFF8671411C6C0717E0E51CFFFFE08382B
S224FE2CA00002C07366024ED608780003C06551CFFFFE60F41C1C67064DFAFFFA60C64ED509
S224FE2CC07807E99D7C0FCC050C060009630406060007060600304DFA000460A851CCFFE46C
S224FE2CE04ED50514051C05248002052C0534056405240524800B053C8006054C0554800E1A
S224FE2D000544055C800F053C0000070D0A455843455054494F4E3A202000070D0A204E4F14
S224FE2D20204D656D6F72792061743A20000D0A4C6F616420446F6E6500070D0A4261642026
S224FE2D404C6F616420436861726163746572000742616420436865636B73756D0007447225
S224FE2D60697665204572726F722000074E6F7420424F4F54204469736B00206F6E20647298
S224FE2D80697665200007424144204D656D6F7279206174200052414D2053697A65203D2038
S224FE2DA000206973200020696E7374656164206F6620000D0A534147452049562053746199
S224FE2DC0727475702054657374205B322E315D0D0A00426F6F74696E672066726F6D2046D9
S224FE2DE06C6F7070790050757420696E20424F4F54206469736B20616E64207072657373AD
S224FE2E002061206B6579202851202D207175697473290007426F6F742041626F72746564E4
S224FE2E20002028546573742041626F727465642900202046696C6C696E67206D656D6F7258
S224FE2E40792E2E2E0020204C6F6164696E672E2E2E00202057726974696E672E2E2E002016
S224FE2E60204D6F76696E67206D656D6F72792E2E2E000750524F4D2031204261640D0A00A8
S224FE2E800750524F4D2032204261640D0A00427970617373656420496E69740D0A004C6F99
S224FE2EA06F7065642054657374730D0A0052414D207772697465206C6F6F700D0A00426F50
S224FE2EC06F74696E672066726F6D204861726420447269766500436F756C64206E6F7420B9
S224FE2EE066696E64200057616974696E6720666F72204472697665205265616479203C51F8
S224FE2F002D71756974733E000D0A4E6F204D6174636820666F756E640020205365617263C2
S224FE2F2068696E672E2E2E000D0A4D617463682061742000202D20436F6E74696E75652073
S224FE2F40736561726368202843203D20596573293F200000001F0027002B003300470052FA
S224FE2F60005C006A007A008F204572726F722061742000556E6B6E6F776E004275730041E5
S224FE2F8064647265737300496C6C6567616C20496E737472756374696F6E00417269746835
S224FE2FA06D657469630050726976696C656765005265736572766564205452415000556EFB
S224FE2FC061737369676E6564205452415000556E61737369676E656420496E74657272752F
S224FE2FE070740052414D205061726974790046756E6374696F6E3A200020204163636573B2
S224FE3000733A20002020496E73743A20000303D1070207000108024A00006100000C423885
S224FE302001C250F801BB4E7548E71C0011FC0000C50708F80000C5037080740011C0C5C15C
S224FE3040723251C9FFFE7A0411FC00B0C60711FC0000C60511FC0000C605323C174051C91B
S224FE3060FFFE11FC0080C60776001638C605E15B1638C605E15B444386FC000C31C301F2DA
S224FE3080967801F067226E1244430C4300026F185202671C530066A460160C4300026F0854
S224FE30A05202670C520060EE51CDFF9E50F801BB11C001EF11FC0001C507303C174051C870
S224FE30C0FFFE4CDF00384E75223801D67000103801B934004841B2406200006E484182C0DD
S224FE30E04841303801B0C4C0C0C142414841944048C231C001E8203801DAB4806D0C9440AE
S224FE310031C201EC31C001EA600831C201EA427801ECD27801BC6530B27801BE622A43F8B7
S224FE3120020030196708B2406504524160F431C101E27000103801B882C031C101E44841A8
S224FE314031C101E642004E7511FCFFF501C34E7511FCFFF201C34E752F02343C07D00838C9
S224FE31600001C58167305342672611FC000CC58772016100011C4A3801C366000092701434
S224FE3180484008380000C58167D45380670260F270FD6000007611FC000DC587720A6100CF
S224FE31A000F04A3801C3660000667014484008380000C5816706538067D660F20838000168
S224FE31C0C58167CC343C07D008380001C5816728534267BC11FC000CC5877201610000B273
S224FE31E04A3801C366287014484008380000C58167D65380679A60F2303C251C51C8FFFE40
S224FE32004200427801C050F801C211C001C3241F4E7508380000C58166604A3801C266064B
S224FE32206100FF3666521038C585020000F8807801E611C0C585323801C0927801E4673204
S224FE32406E0A444111FC000DC587600611FC000CC5876100003C4A3801C3661C72FFE0196E
S224FE326008380000C58157C9FFF6660E31F801E401C0700011C001C34E7570FD60F610389A
S224FE3280C583020000F0803801BA11C0C5834E7548E7E000E349534111FC0036C60711FCB6
S224FE32A000B0C607303801B211C0C601E04811C0C601741851CAFFFE11C1C605E05911C1CF
S224FE32C0C605741851CAFFFE08B80000C503343C08EC51CAFFFE720C484111FC0080C60717
S224FE32E01038C605E1581038C605E158670C6B0A538166E611FCFFFD01C308F80000C50396
S224FE33004CDF00074E7543F8C7C1247801DE08F80007C50311FC000FC50711FC000DC507DA
S224FE332011FC000CC5074A114A1111FC0003C78311FC0041C7851011E148101131C001C4DA
S224FE3340343801E8670853424A1151CAFFFC343801EA534214D151CAFFFC343801EC6708F1
S224FE336053424A1151CAFFFC4A114A1108380000C7836610303801C4B07801E2660E423868
S224FE338001C34E7511FCFFF801C34E757400143801B880C231C001C011FCFFF401C34E7524
S224FE33A011FC0002C50711FC0008C50708F80006C50308B80007C50311FC000DC50711FCFE
S224FE33C0000CC50711FC000EC50711FC0030C60711FC0070C607303801B411C0C601E048FA
S224FE33E011C0C601303801B611C0C603E04811C0C60311FC000BC50711FC000AC50708F8F0
S224FE34000001C50370FF08380004C58156C8FFF8660611FCFFFA01C308B80001C50311FC06
S224FE34200008C50708F80006C50311FC0005C50708F80007C50311FC000FC5074E75225F0E
S224FE344021DF01DA21DF01DE21DF01D62F096100FE2E4A3801BB66046100FBC011FC000A38
S224FE346001EE423801C308380005C581660000564A3801BB66046100FBA24AB801DA6700EB
S224FE348000AA6100FC44660000426100FD864A3801C3660000366100FF084A3801C366005C
S224FE34A0002A6100FE62660000227000303801EAD1B801DE91B801DA80F801B048C0D1B88D
S224FE34C001D6609811FCFFFC01C3533801EE6F00005A103801C30C00FFF967260C00FFF86B
S224FE34E067200C00FFF7671A0C00FFFA67100C00FFF4660000360C38000301EE6C04423888
S224FE350001C2303CFFFF51C8FFFE523801FF103801FF0200001F670A0C38000501EE660063
S224FE3520FF426100FB046000FF3A1038C583020000F011C0C583103801C34E75225F261F1E
S224FE3540321F700003C011C001BAE90911C101F42F09423801BB11FC000101B811FC00134A
S224FE356001B931FC020001B031FC004001B431FC004801B631FC177001B242780200427883
S224FE358001BC427801BE6100FCF6722F484108380005C581673441FAF94E6100CE706100CD
S224FE35A0CE48600808380005C581671E6100CF46670A6100CF480C0000516704538166E435
S224FE35C011FCFFFC01C36000FF6270FF08380005C58156C8FFF86700001248410C41002FCE
S224FE35E057C048414A0066AE60BA42A741F804002F08203C000004002F006100FE426600BD
S224FE3600FF2A7010B6806D2E204343F8060076002211B290660A22290004B2A80004671604
S224FE3620D2FC00205243B67C00106DE411FC000101C36000FEF6873801F4E54B41F804002A
S224FE364031F0300001BC31F0300201BE11E801F601B911E801F701B831E801F801B031E817
S224FE366001FA01B431E801FC01B631E801FE01B2D0FC004043F80200701F22D851C8FFFC19
S224FE36806000FEA82C5F11EF0004010508F800010105422F00046100CFC446FC270011FCA6
S224FE36A00025C073423801046100CD3E41FAF8106100CD5A6100CD326100FE82665242A717
S224FE36C0307C04002F082F086100FD74661C307C04000C58424F662E0C584F546628700037
S224FE36E0103801F43F002F0E4ED06100CCFC103801C3440041FAF6676100CD126100CD1C55
S224FE37006100CCE64ED641FAF6636100CD0060F00C38000101C366D26100CCCE41FAF7B837
S224FE37206100CCEA41F801F66100CCE260D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
S224FE3740FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
S224FE3760FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
S224FE3780FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
S224FE37A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
S224FE37C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
S224FE37E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
S224FE3800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
S224FE3820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
S224FE3840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
S224FE3860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
S224FE3880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
S224FE38A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
S224FE38C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
S224FE38E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
S224FE3900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
S224FE3920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
S224FE3940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
S224FE3960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
S224FE3980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
S224FE39A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
S224FE39C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
S224FE39E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
S224FE3A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
S224FE3A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
S224FE3A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
S224FE3A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
S224FE3A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
S224FE3AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
S224FE3AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
S224FE3AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
S224FE3B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
S224FE3B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
S224FE3B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
S224FE3B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
S224FE3B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
S224FE3BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
S224FE3BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
S224FE3BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
S224FE3C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
S224FE3C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
S224FE3C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
S224FE3C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
S224FE3C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
S224FE3CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
S224FE3CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
S224FE3CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
S224FE3D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
S224FE3D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
S224FE3D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
S224FE3D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
S224FE3D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
S224FE3DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
S224FE3DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
S224FE3DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
S224FE3E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
S224FE3E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
S224FE3E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
S224FE3E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
S224FE3E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
S224FE3EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
S224FE3EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
S224FE3EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
S224FE3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
S224FE3F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
S224FE3F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
S224FE3F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
S224FE3F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
S224FE3FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
S224FE3FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
S224FE3FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
S804FE0000FD

29
SAGE/FILES/sim2bin.c.txt Normal file
View file

@ -0,0 +1,29 @@
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char* argv[])
{
FILE *in,*out;
unsigned int n,i;
unsigned int c[16];
char buf[101];
if (argc != 3) {
fprintf(stderr,"Usage:\n\t%s txtfile binfile\n",argv[0]);
exit(1);
}
in = fopen(argv[1],"r");
out = fopen(argv[2],"wb");
while (!feof(in)) {
fgets(buf,100,in);
sscanf(buf,"%x: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
&n,c,c+1,c+2,c+3,c+4,c+5,c+6,c+7,
c+8,c+9,c+10,c+11,c+12,c+13,c+14,c+15);
for (i=0; i<16; i++) fputc(c[i]&0xff,out);
}
fclose(out);
fclose(in);
exit(0);
}

BIN
SAGE/FILES/system.imd Normal file

Binary file not shown.

15
SAGE/FILES/ucsd.sim Normal file
View file

@ -0,0 +1,15 @@
set cpu debug=int
set cpu debug=exc
set cpu 512k
set debug debug.log
break fe1ad6
set fd debug=verbose
set fd debug=cmd
;set fd debug=seek
;set fd debug=irq
;set fd debug=state
set fd debug=status
set fd debug=rddata
att fd0 system.imd
boot cpu

514
SAGE/FILES/v2-04.hex Normal file
View file

@ -0,0 +1,514 @@
S00C000076322D30342E68657853
S224FE00000000040000FE0044600004F8600004EC600009646000044E600003F8600003D0DE
S224FE0020600003FE60000404600029A8600029AA6000033AF58A0204600002FC6000344C30
S224FE0040600037144E704FF8040011FC0092C02711FC0038C02511FC0092C06711FC003135
S224FE0060C065700072FF343C42D741F8C0FE3080308151CAFFFA43F8000045F87FFE343C1D
S224FE0080344230113010301251CAFFF8343C06C541F8C00172084A10D0FC001051C9FFF81C
S224FE00A051CAFFEE43FA0006600002C649FA2D0B4BFA000660002C0441FA00362278000861
S224FE00C021C80008B1F80008662E11FC0090C58711FC0090C50711FC0000C58311FC00CD66
S224FE00E0C50311FC0000C58511FC0005C50560044FF8040021C900081038C0216B64E6087B
S224FE010002400006303B00064EFB000200180024001800084238010449FA2DB74BFA085831
S224FE012060002B9849FA2DBB4BFA003860002B8C49FA2DBE4BFA000660002B8074FF720071
S224FE014070001038C023460008000002670272FFE308024000064840204030C151CAFFFCB5
S224FE016060DA41FAFE9C343C1FFF42004201D018D21851CAFFFA4A00671449FA2D394BFAC1
S224FE0180000660002B364A38C0216A0001004A01671449FA2D2F4BFA000660002B1E4A38EC
S224FE01A0C0216A0000E811FC0001C067307C000072014841323CFFFE224145FA00066000B9
S224FE01C02A3A664647FA000C21CB000808F80002C5034FF8040047FA002421CB00087202E9
S224FE01E04841D3C1303CA5A53280B051660E46403280B05166064640D3C160EC4FF80400AC
S224FE020093C145FA0006600029F267084A38C0216A00007A303C00BF41F80100429851C8B9
S224FE0220FFFC548921C901004E6121C9014A21C9014243FA000C21C9000808B80002C50322
S224FE02404FF804006100041C11FC0000C0674A38C0216B1611FC0007C06770FF51C8FFFEF7
S224FE026011FC0006C0676000FEFA6100018241FA2B2B6100019E30380100ED486100021C57
S224FE0280704B610001E06100016660044E7227007228740208380006C0216702725011C216
S224FE02A001C611C101C7423801CA11C201CE11C101CF11FC000101D27206610000FE42381F
S224FE02C001BA2278000841FA003021C8000811FC00AAC58311FC0005C5050C3800AAC58351
S224FE02E0661611FC0000C58350F801BA31FC027001F011FC008001F54FF8040021C90008D7
S224FE03001038C021C07C0030670CB07C00206724B07C0010672621F80100014A21F80100B3
S224FE0320014231FC2700014E41FA004221C801466000064442676100280860DA4A3801BACC
S224FE034067D4203801004840720C92406F12C2FC000A5341303C6F9A51C8FFFE51C9FFF6B7
S224FE0360426770012F006100356A60AA4E4F60FC41F8C0734200108011FC0076C007E018AE
S224FE038010801238C021E0181080706E080100036702707E10BC00400241000711FB101450
S224FE03A0C003108011FC0000C003E01810BC00254ED1028040201008040241F8C033424061
S224FE03C0108011FC00B6C007E018108011FB10E4C005E018108011C0C005E01810BC004091
S224FE03E0E01810BC004EE01810BC00274E752F00700D6170700A616C4200616861666164DF
S224FE040061626160201F4E752F0070206156201F4E753F0010186704614A60F8301F4E75F4
S224FE0420E9186126E91861224E752F017203E958611851C9FFFA221F4E752F017207E9984A
S224FE0440610851C9FFFA221F4E753F000200000FB03C0009630406000007060000306104C5
S224FE0460301F4E754A380104662C3F01323CFFFF08380002C07356C9FFF8670811C0C071A6
S224FE0480321F4E7548E7C0C043FA00066000FEE24CDF030360D64E4A4E7548E7F0007200C0
S224FE04A032007400343C2710420382C266044A0367061001619450C34241484184FC000A90
S224FE04C066E84CDF000F4E754A38010466282F011238C0730801000167F61038C071020129
S224FE04E000386604221F4E7511FC0035C07370076100FF7260DA4E494E7508380001C0738D
S224FE05004E7561C4088000070C0000616D0A0C00007A6E04088000054E7521C001067002DB
S224FE0520604E21C001067004604621C001067006603E21C001067008603621C00106700AB4
S224FE0540602E21C00106700C602621C00106700E601E21C001067010601621C001067012F4
S224FE0560600E21C001067014600621C00106701648F87FFE010A4E6821C8014A2A00701668
S224FE0580BA806270BA3C00046206381F261F341F31DF014E21DF014621CF01424FF80400D7
S224FE05A00C0500146700199A6E0018B80C050012661E11FC0001C06711FC0000C0674A3829
S224FE05C001BA670C08F80002C50308B80002C50370FFE01851C8FFFC46FC270011FC00386D
S224FE05E0C02508B8000601504238010443FA000A6000FD7E428560A849FA27164BFA0006C1
S224FE0600600026B849FA2990D8F450004BFA000460EE49FA29964BFA000460E420380146BC
S224FE0620610017F66100FDC80C0500046200034841FA29FE6100FDDC30046100FDEE41FA0A
S224FE064029FB6100FDCE20036100FDF041FA29F86100FDC030026100FDD26100FD926000AA
S224FE0660031641F8000843FA268045FAF9944280301967186B06D08A20C060F24241120052
S224FE06803019D08A20C051C9FFFC60E24E75225F02800000000FD080D089C1893251D3C09F
S224FE06A04ED148E780B02478000847FA001421CB0008101121CA00084CDF0D01B0004E750C
S224FE06C0508F321F46C141FA26586100FD46588F20096100174421CA00084CDF0D0100008B
S224FE06E000014E7508380001C0734E752F00703A6100FD72201F6100FD104E752F00702C18
S224FE07006100FD62201F4E752F0070076100FD56201F4E75C03C007F0C0000206D060C0092
S224FE0720007E6D02702E4E752F092F01224842816100FDD00C00001B6700006E0C0000128B
S224FE0740670000680C00000D674A0C000008661AB3C867DC6100FD0E6100FCAE6100FD06D0
S224FE076051C9FFF25389528260C40C00007F6614B3C867BC61585389528210116100FCE627
S224FE0780544160AC611A428153826B0812C06100FCD4609C610A421912C0221F225F4E7513
S224FE07A08281673C4281602C224842812F0870236100FCB26100FC38B3C86700000C101890
S224FE07C06100FCA2B3C866F6205F6000FF648281660E72013F00103C005C6100FC88301FF9
S224FE07E04E75428010188000660253884E7561F28000670A0C00002067040C00002C4E75ED
S224FE080061E067080C00002067F653884E7561D2244942411219B011568957C9FFFA660091
S224FE082001481021E1581021D4C04ED248E7180042817801E89C61B667540C00002F660E95
S224FE0840383C33334844383C333461A26740040000306D380C0000096F144A04662E040053
S224FE086000070C00000A6D240C00000F6E1E26014A046708E799E39BD2836002E999B684CB
S224FE0880640AD280848267C2B48164BE72FFC1414CDF00184E752F036100FF66428395CA7A
S224FE08A06100FF4C670000480C00002367360C0000246708347801525388602A6100FF307B
S224FE08C06700002C0400003065240C000003641E244093C96100FF18670000180C00002B46
S224FE08E0660C6002528342826100FF42670257832240D5CAD5CAD4FC0154D3D2201FC143F6
S224FE090080804E752F0242826100FEF6670000520C000027671C0C00002E674624016100EB
S224FE0920FF0C6B06241F92814E75241F428153814E756100FEAE6100FEAA670000200C00D9
S224FE094000276712E19A4A0266E0D480828167E6B28264E260D46100FE9666CEC14260C445
S224FE09607001241F22004E756100FA9E703F6100FAF46100FD944FF8040042B801546100F7
S224FE0980FA6E0838000601506700000870546100FAD436380152670C70246100FAC81003F5
S224FE09A06100FAA8703E6100FABC742841F801886100FD7643FA1A686100FE5460B843FA73
S224FE09C01A8C6000FE4A6100FE382838017E387801821010670E6100FEBE668C2809284AD6
S224FE09E031CA01826100FE1A327C01001010670A6100FEA46B00FF726704D3C45389528925
S224FE0A0021C9017E2A09611C6718280B6100FCD667F46100FAEE0C00001367F60C000003A6
S224FE0A2066E44E756100F9C820046100FA0EB8FC0154670C6100F9D2200490946100F9FCB1
S224FE0A406100FCAA760F2644C7496100FC56C7496600FF16101B6100F9C808030000660091
S224FE0A6000066100F9A4BA8B57CBFFDE6100F99A760F2644101B6100FC9C6100F9E8BA8B9D
S224FE0A8057CBFFF24E7543F80154323C20247402601443F80126323C2041600843F8010676
S224FE0AA0323C204474076100FD3A671A903C00306B00FEB678001800B8026E00FEAC6122CD
S224FE0AC06100F92C4E754284611852846100F93A0C04000466046100F9306130B8026DEA77
S224FE0AE04E756100F90A42833001E0880C000020670000066100F96E10016100F968868331
S224FE0B00660610046100F9446100FBE22004E5800280000000FF4A836A4230310000610031
S224FE0B20F90A0C415352663C48E7704036006100F8D870286100F92E428243FA18D214199D
S224FE0B40670E1019E57B650270206100F91860EE4CDF020E70296100F90C600820310000EA
S224FE0B606100F8D84E756100FC7A6600FDFC6100FF226100FF2861186108614861046134B9
S224FE0B804E756100F8846100F8804E756000F86061FA103C00506100F8CC103C0043610052
S224FE0BA0F8C46100FB4820380146307801526000126861D876FF43F8014E223C0000535223
S224FE0BC0600E61C843F8014A223C00005553760142846100FF144E757C0060000C2C7000F7
S224FE0BE072104A10670A6100FC446B00FD7C12006100000E5200B0016DF66100F7F24E752C
S224FE0C006100F7EC41FA00206100F8086100F83C41FA001B3438017C0102670441FA001B39
S224FE0C206100F7F04E755452415020230020204E6F207472616365200020205472616365B1
S224FE0C4020202020000043FA18A26000FBC26100FCB46600FD142A006100FCAA6600FD0AD7
S224FE0C602800D0856100F7882200103C002B614822059284103C002D613E2205C2C4103C84
S224FE0C80002A61344A446746220582C4103C002F61186132103C00726100F7CA103C0065D2
S224FE0CA06100F7C2103C006D48416100F7B86100FA3C30016000F7746100F7AA6100FA2EA7
S224FE0CC020016100F7766100F7406000F73C4E757C106100FB2C2838017E387801821010EE
S224FE0CE067106100FBB26600FC802809284A31CA01826100FB0C327C00141010670C7CFF31
S224FE0D006100FB946B00FC6267062C096B00FC5A52892A092C446100F6D6200E6100F71C67
S224FE0D20B8FC0154670C6100F6E0200E90946100F70A6100F9B848E7060061304CDF0060E6
S224FE0D4021CE017E4A866B065386671E2A0EBA8E650000186100F98E67BC6100F7A60C0071
S224FE0D60001367F60C00000366AC4E75300EE2086500FBF67C07610006F03E00E9586100E4
S224FE0D80F90E0020010001080104014003880428046E0512060606CC053A05A6060606526D
S224FE0DA006CC08070008664E43FA176C3207E049E249610006F659016F5E040100106758EE
S224FE0DC0580166064245611C60063A07610006C4610006FC6100070216076100F9206100B0
S224FE0DE007364E75428543FA171E3207EC5902410003600006B63007020000380C00000852
S224FE0E0067367042610006AE61DA610006C23607EC5B6100072860C030070200003F0C004F
S224FE0E20003C66A64282263A084C080700066704263A0846600000F2203A082A6100067606
S224FE0E407050610006703A07E35D08C500066100064E6100067A08070007670A61126100B3
S224FE0E60F89C61144E7561106100F89261024E753607EC5B600006C6360708C30005600004
S224FE0E800696428560067A4060027AFF203A07D6610006223007EC580200000753006606EE
S224FE0EA0704161000610610005F6610006223607610006646100F8463607EC5B610006642C
S224FE0EC04E7508070008660002043007EF580240000732006100F7B8001000320014001C4E
S224FE0EE0007C011800B201527401600A263A0786428260064282263A0780283A07683007AC
S224FE0F00020000C00C0000C0671843FA16366100059A3A076100057C610005B4610005F69F
S224FE0F204E7520046100058E7A40610005A228034A026614610005DE4A84670A6100F7BE87
S224FE0F402004610005704E7561F66100F7B0610005C44E753207E6590241000708070007AD
S224FE0F606624203A071808070006670C203A07124A016604203A070E6100053A61000550F6
S224FE0F80610005924E754A016756203A06D861000524704D3A07E35D08C50006610005163C
S224FE0FA0610004FC610005287A40610004BC31C001880807000A661E6100000C6100F73E4A
S224FE0FC0610005524E7570236100F49A303801886100F4584E7561E86100F72261E84E75E1
S224FE0FE0203A06AA08070006678E203A069C60880C0700FC6612203A0698610004B8203A00
S224FE10000694610004B04E753A07024500C00C4500C0670A3005E2588A406000FEEE283AAA
S224FE10200678428242836000FED608070007660000983207E6590201000714010C010006B4
S224FE104067520C0100036F14263A065E024200010247000F004700C86000FEA043FA14FC86
S224FE10606100044861000468E20A660E70236100F3F430076100F3D44E753607E75B6100B6
S224FE108004C008070003660A6100F6727A40610004484E75320702410007340143FA14CC3F
S224FE10A0610004080C020002660A610004227A406100042670544A02670870560C0200061B
S224FE10C066046100F3A04E754280600270023207EC59C27C0001D2407A4043FA14AE61006D
S224FE10E003CA610003EA6100042C0807000867186100F60A3607EF5B7020080700066702B5
S224FE11007028B143610004104E753207020100C00C0100C0673E203A058808070008670431
S224FE1120203A05826100038E3A07610003666100039E70236100F32E3007EF580200000730
S224FE11404A00660270086100F3026100F5B0610003C44E7570533807020400380C040008C3
S224FE1160660808870003303C4442611C610003A60C04000866106100F5847A40610003600D
S224FE11803440610003FA4E7543FA1440610003263207EE5902810000001ED3C142803011E4
S224FE11A061000312610003284E757A40320702410F000C410100670A704243FA13EE61CC46
S224FE11C0600C203A04D8610002EC6100030230074A0067106100F24AE158E040548E61087C
S224FE11E0558E4E75610002F83440610003924E750807000866000258203A046A610002B606
S224FE12007051610002B0610002C670236100F25610076100F20C6100F4E43607EC5B6100FE
S224FE1220031C4E753A0743FA13C2612208070008670C61106100F4C6610002DA4E7561F884
S224FE12406100F4BA3607EC5B610002F24E753207E95902410007610002524A45670461000B
S224FE126002326100026A4E75428560023A0743FA139A61DA3607E75B61086100F48036071E
S224FE1280EC5B080700036606610002B24E75610002C04E753007024001F00C40010067C8E2
S224FE12A0EC4872045740670859406600FF787205088700068E7C41006000FE1E3007EC58B7
S224FE12C00240000755406F00FF5C43FA133E7A4053406706E35D594066166100FF72610093
S224FE12E002346100F4183607EC5B610002544E75044710003007024000380C400008660084
S224FE1300FF24203A03A8610001AC3A0761000184610001BC3607E75B61086100F3E03607F6
S224FE1320EC5B610002264E753007024001F878000C400140671078030C4001486708780230
S224FE13400C4001886624203A0368610001686100017E3607EC5B61086100F3A23607E75B5A
S224FE1360E21C650001DC600001D4E8480C0000106700FEF67206E44857406700FF34720700
S224FE1380594067F66000FE9E3007024000C00C4000C067123007024001300C40010067003C
S224FE13A0FECC6000FE803A07E25D43FA12563207E55902410001610000F2610000E26100AB
S224FE13C0010E610001506100F3343607EC5B610001704E7532073A07024500C00C4500C016
S224FE13E06744E6596150610000AA610000E2360702430E00080700056708EC5B6100013E07
S224FE1400601670236100F05E3003EF580200000F660270086100F0346100F2E23607E75B6D
S224FE14206100011A4E75EF59610C4285610000A0610000E24E750241000334070242010021
S224FE1440EC5A824243FA11DC610000604E75702E61000062203A02126100005A6100007076
S224FE146030076100EFC64E752F09224E6100F2346600F4F6301E225F4E752F09224E61003F
S224FE1480F2226600F4E454896100F218201E225F4E75024500C00C05008066027AC03205BC
S224FE14A0EC590201000343FA108AE519024100FF203110002F017203E1984A00670000088F
S224FE14C06100EFA2530651C9FFF0221F4E756100EF3851CEFFFA4E7570236100EF883205AC
S224FE14E0EC59C27C0003B23C000267206100FF7A53016C066100EF2A4E756100EF2E53013D
S224FE15006D086100FF646100EF224E75703F6100EF544E7536071003E60802000007E70B0B
S224FE152086001003024000076100F164001000140018001E00240076008000C672446014AC
S224FE154072416010223A0112600A223A01106004223A010E7403E1991001671C6100EF0675
S224FE15600C00004467060C000041660C3003E618020000076100EED451CAFFDC4E75705B0B
S224FE15806100EEE2D5CE200A558030780152D1C8D1C890A801546100EEA2705D6100EEC6E8
S224FE15A04E756100FEC46100EE8260986100FEBA38006100EE6C70286100EEAA6182610098
S224FE15C0F13C3604EF5B0804000F66066100FF6E60046100FF6C702E6100EE8A7057080488
S224FE15E0000B6702704C6100EE7C70296100EE764E75E61BC63C000710036100F0920012BA
S224FE1600001C0026003E00540010001000104E756100FE566100EE144E756100FE5E610007
S224FE1620EE1A4E756100FE4234406100EDFE223A003C6100FF206100FF464E756100FE2A71
S224FE164038006100EDDC203A00286100FE686000FF6E6100FE844E75284129002841292B1A
S224FE16602D2841294D4F5645574F5244285043292850430043435200535200004E42434402
S224FE168050454100535741504558544C45585457494C4C4547414C005441530042535200E8
S224FE16A0414444515355425155535000434D504D4558470043FA0DB56000F1546100F1D8FB
S224FE16C06600F2A660046100F0402809284A2A0454856100F3506100F01441F80188243C3F
S224FE16E0000000286100F042428110106716223C0000FFFF6100F20E6BCC6E0A134000010C
S224FE1700E080128054890C01002E66BE4E7543F80154323C202474037A01601643F80126C9
S224FE1720323C2041600843F80106323C2044740842856100F0AE671A903C00306B00F22A15
S224FE1740B0056B00F224B0026C00F21E4282610E4E75200561085280B0026DF84E7542832D
S224FE17602F023A0128002C00E5864A82660E6100F0904A10662260046100EF8E320561005E
S224FE1780EC6E6100F3646100EF64742841F801886100EF961010672042816100F1686BD8D5
S224FE17A0660000160286000000FF86836A063380600060042380600032051004241F4E75DF
S224FE17C06100F0206600F1A26100FF526100FF586106611E610E4E7543F80146323C504397
S224FE17E06000001843F8014E323C535276FF6000000C43F8014A323C555376014282428057
S224FE18006100FF5E4E757CFF7A0142806100EFD467144486903C00306B00F14EB03C000190
S224FE18206E00F1463A00360060046100EEDC3643D7CB284BD7CB4A866B0A675A6100EFC2B9
S224FE18404A106614616A6100EEA4742841F801886100EED66100EFAA101067320C00002E83
S224FE1860660607B8015060266100F02C6BBC6100EF90243C0000FFFF6100EFB26BAC426CBA
S224FE188001723940017607F80150274901605243B6456F9A4E75611860F4427265616B7043
S224FE18A06F696E742000496E61637469766500006100EB3C41FAFFE46100EB58100361005A
S224FE18C0EB8A6100EE2807380150660A41FAFFD86100EB404E75202B01606100EB5E610001
S224FE18E0EB2870286100EB7E302C01766100EB3C6100EE0A302C01726100EB307029610077
S224FE1900EB644E75760078104A10671C6100EF1E6B00F056160018006100EEE60C000054F5
S224FE192067460C00004E67386100EAC441FA004C6100EAE010036100F2C86100EDB0742875
S224FE194041F801886100EDE26100EEB667240C00005467140C00004E67066100EDAC60C83E
S224FE19603238017C078160063238017C07C131C1017C5203B6046DBC4E752854297261639B
S224FE198065206F7220284E296F2074726163650043FA0AF86000EE78243C000000FF616C50
S224FE19A06600EFC61A00E1401005600C243C0000FFFF61586600EFB23A00484030056008D0
S224FE19C0428261486600EFA241FA14AA6100EA4461000942E19812C0538466F821CA0008F9
S224FE19E04E7548E7F0006100EEAE661A28096100EEA62449C9896B0E6E0698895284600458
S224FE1A00D5C9538A42804CDF000F4E7561D4660622026100EEF04E7561F266142C009887AA
S224FE1A206D00EF4670FF4A10670A22026100EED66600EF3641FA15266100E9D8610008D61C
S224FE1A404E7543FA0AB46000EDC6243C000000FF7E0161C41219C200B206670453846CF468
S224FE1A606100009660F6243C0000FFFF7E0261A81219E1991211C240B246670453846CF0CF
S224FE1A806100007660F642827E04618C2649548B1219E1991211E199121BE1991213C28045
S224FE1AA0B286670453846CE86100004E60F66100FF326600EEB448E708606100FF26660033
S224FE1AC0EEA82A492C044CDF0610C34D41FA148E6100E9406100083E9C8465182849528982
S224FE1AE02E04264D121CB21B6606538766F6610853866CE861024E7148E7FE7E663E41FA5F
S224FE1B00146B6100E90E538920096100030C6100EBDC7203E198101951C9FFFA6100E91CBE
S224FE1B2041FA14556100E8EC6100E9D80C00004366126100E9304CDF7E7F4E7541FA140D1F
S224FE1B406100E8D04CDF7E7F21CA00086000EE286100E8B66100E8B243FA093A6000ECB062
S224FE1B6043FA093C6000ECA86100ED2C6600EDFA20096100E8C66100EB7410116100E8A221
S224FE1B804E756100ED126600EDE03C09080600006600EDD620096100E8A26100EB5030117F
S224FE1BA06100E8884E7543FA08FD6000EC626100ECE66600EDB4223C000000FF6100ED4673
S224FE1BC06600EDA612804E756100ECCC6600ED9A3C09080600006600ED90223C0000FFFF1C
S224FE1BE06100ED226600ED8232804E756100EC1274076100EC386B00ED7022006000E7BCDC
S224FE1C0043FA08AA6000EC086100006443FA07B654894A516700ED523014C059B05966F0E5
S224FE1C20D8D121CC016808F80002015008F800040150600261387401610001BA426A01724F
S224FE1C4051CAFFF66002612608B80005015008F80006015008F80007015010380150020028
S224FE1C600007660608B800060150600001506100EB901010670C6100EC1E6600ECEC21C924
S224FE1C80014661066100E7684E752C380146284608060000671241FA001C6100E776200645
S224FE1CA0610001766000ECD0224C6100E9F66600ECB84E75496C6C6567616C2070726F6720
S224FE1CC072616D20737461727420616464726573733A20006100E71843FA07DC6000EB3018
S224FE1CE0083800060150670461A0604E4E7508F8000501506040619208B8000301500C1054
S224FE1D000049660808F80003015052887005083800050150660270104A10670E747F6100C5
S224FE1D20EAE06100EB086B00EC406100E6C2600C08B8000501506100FF36700111C0015136
S224FE1D4008F80006015008B80007015030140240FFF00C404E406664301C0240000F3C38E7
S224FE1D60017C41FA002C0106661C21CC016808F80007015008F80002015008B800040150DD
S224FE1D80673A41FA00216100E68A6100E662602C2A2A2A2054726163696E67205452415080
S224FE1DA0202A2A2A002A2A2A204753207465726D696E61746564202A2A2A00002878014678
S224FE1DC03C38014E08380006015066060886000F600408C6000F2078014A4E602E780142E2
S224FE1DE02F0C3F064CF87FFF01064E7308B8000601504E7542803242D3C92449D3C90538E4
S224FE1E000150670E226901606100E8986600000652804E7553804E756100E6203078015233
S224FE1E20D0C8D0C84A780152672E6100E5DC2F0070286100E63070246100E62A30380152A5
S224FE1E406100E6086100E8A6201F90A801546100E5EA70296100E60E4E7554726163653A6B
S224FE1E6020000838000601506700FF52083800070150672608B80006015074006100FF766A
S224FE1E806B00EAE667083551016C32BC4E4F52420C42000366E66000FF2441FAFFBE203813
S224FE1EA0014621C0017E6100E56A28406100FF6AD0FC015431C801826100E832224C6100AF
S224FE1EC0E7E2661430116100E5626100E53C6100E5382C496100EE96083800050150670A72
S224FE1EE041F8018842106100EC7E533801516F1E083800030150671A6100E7EA6714610073
S224FE1F00E6020C00001367F60C00000366046000EA666100E4DA6000FE280D0A556E6578D5
S224FE1F2070656374656420627265616B20706F696E743A2000000D0A427265616B3A20000A
S224FE1F4042854286283801465584760041FAFFCC74026100FEA06F32B3C4661E41FAFFD8D0
S224FE1F6076020C02000267123A2A01723C2A0176BC4567065245354501720C514E4F670650
S224FE1F8005B80150600432AA016C51CAFFC60838000201506728B8B80168662208B800025E
S224FE1FA0015008B800040150661421C4014608F80006015008B8000701506000FEA6203847
S224FE1FC00146908321C00146BC456600FC824A436600FED028440C544E4F6600FEC620041F
S224FE1FE06000FEC043FA04E46000E82411FC000101BB6004423801BB41FA0E8E6100E4149B
S224FE20006076428574016100E8246B00E95C3C00243C0000FFFF6100E8146B00E94C3F00B8
S224FE20206100E8746600E9422F0942826100E7FE6B00E9362F003F064A85670E41FA0E572B
S224FE20406100E3D061000992600C41FA0E3C6100E3C26100097E6700000E41FA000C610071
S224FE2060E3B26100E3BC4E750D0A4469736B206572726F723A20000061740C000051670026
S224FE208000C00C00005366F0420561621E00610000BC1C0153064281610000B2610000AE28
S224FE20A026410C070030660E4A0667066100009E60F6617460C20C0700326614220B6100A9
S224FE20C0008C26414A0667EA6100008216C160F40C07003167EE0C07003966644A06666096
S224FE20E0614641FA0C4F6100E32A6000E88A4A3801BB672408380001C033670A1038C031B9
S224FE2100088000074E756100E3F267E26100E3F40C00005166D84E756100E3AE0C00000D4A
S224FE21206700E2CC6000E33E6122460566024E75588F41FA0C216100E2DA6000E83A508F40
S224FE214041FA0BFD6100E2CC6000E82C61086106DA0153064E7561960C0000306DE00C0063
S224FE216000396E0A04000030E989D2004E750C0000416DCA0C0000466EC45F0060E643FA86
S224FE218003436000E68A7A016000FE7A6000E7E843FA03426000E678202053797374656D9F
S224FE21A0207265696E697469616C697A696E672E2E2E2E0046FC270011FC0025C07342381A
S224FE21C0010441FAFFD46100E24A70FF51C8FFFE6000DE724280428710100C0000526606B2
S224FE21E03E3C010052881010670A74016100E63E6B00E77680473F00610009464E754A3839
S224FE220001BA6700E764428042877C0110100C00005266063E3C010052881010675C0C0018
S224FE222000206714040000306D00E73E0C0000036E00E7368E0052886100E5C64A00673A41
S224FE22400C0000236600001652884A10672C740F6100E5DA6B00E7123C00601E740743F892
S224FE226001F62C09429142A90004422900086100E572670612C051CAFFF63F072F06610017
S224FE228016524E754E7574186100E16451CAFFFA4E7543FAE2D621C9002443FAE2C621C972
S224FE22A000BC4E7542801010670A74026100E57E6B00E6B631C00152E540D07C015431C00D
S224FE22C001824E756100E5D06600E69E28096100E5C66B00E694C98966049889600253847D
S224FE22E06500E68626496100E5AE6600E67C41FA0BB26100E11E7201B7C96406D3C4D7C4F8
S224FE230072FF61101293D3C1D7C153846CF621CA00084E752478000849FA000821CC000834
S224FE23204E7541FA09FC6100E0EA548F201F6100FAE821CA00086000E63E43FA01B560003D
S224FE2340E4CE3F3C00016002426774016100E4DE6B00E6163F00243C0000FFFF6100E4CE92
S224FE23606B00E6063F00427801CC427801D411FC000101DB3F172F3C000004002F3C000094
S224FE238010003F2F000C4A6F001067066100064A60046100063E662A702E6100E0C808F889
S224FE23A0000101DB6100E15467CA6100E11C11FC0007C02711FC0009C027423801DB5C8FDF
S224FE23C04E75705860D4F0FF60000004F00060000002F0F850C80004FFB84E900002FFB844
S224FE23E04EA80004FFB84EB00004FFBF4EB80004FFBF4EB90006FFBF4EBA0004FFBF4EBB03
S224FE24000004FFF04E400002000000000000015402530958014E015A0156014300000E4494
S224FE2420A0E55396F24672F52486FE4DA6FE5032F754B6F847E2F75760FD4CC6FB00C2F8DD
S224FE24404972FD4128E8451CFF5824F6094D7AE5521AE74450E64146E65044E75366E7553F
S224FE246076E7243AE6428CE75492E7094D51F25255F344BBF241B1F2506DF35379F35587E3
S224FE2480F324A3F2429BF35499F402420EF55722F54C36F50249CCF64F12F75358F7014266
S224FE24A0CAF657E4F6014209F75723F7024F88F7439AF7535CF703427AF84536F95238F87D
S224FE24C04E40F80141C9FC46C3FC024122FB542AFB4638FB064600FD482AFD47B0FD53E036
S224FE24E0FC568EE143B2FD54BEFD0144E6E75264E7015257FE5751FE034252F5576EF54C88
S224FE25008EF54DB6F5005453540043484700434C5200534554004F524900414E44495355F5
S224FE252042494144444942000000454F5249434D50492E4200002E5700002E3F00002E4C85
S224FE254000004E454758434C52004E4547004E4F54000000000054535400545241505452C2
S224FE256041504C494E4B554E4C4B524553454E4F500053544F505254450034453734525488
S224FE2580530054524150525452004A5352004A4D500043484B004C45410044495655444973
S224FE25A056534D554C554D554C535241460048494C53434343534E45455156435653504CBF
S224FE25C04D4947454C5447544C455400460048494C53434343534E45455156435653504C1D
S224FE25E04D4947454C5447544C454F52000053554200454F5200434D5000414E4400414441
S224FE260044005355424141444441534243445355425800000000434D504141424344414430
S224FE26204458415352004C535200524F5852524F520041534C004C534C00524F584C524F35
S224FE26404C0048E760401219143C00AD1038C0510800000756CAFFF6671A080000066614AE
S224FE266011D9C053740951CAFFFE530166DA4CDF02064E7511FC000101C560F248E7604046
S224FE268043FA09D461BC6624720243F801C36174661A123801C3020100C0670C080100065B
S224FE26A0670472036002720211C101C54CDF02064E7548E76040720743F801BC421161449B
S224FE26C0663C123801BC020100C0672E0801000667267205103801BDE208651E7206E4080C
S224FE26E065187207E40865127208E208650C7209E4086506720A6002720211C101C54CDFC2
S224FE270002064E75343C10FE1038C0510800000756CAFFF6671608000006671012F8C053D1
S224FE2720740951CAFFFE530166DA4E7511FC000101C54E752F017002484008380000C06386
S224FE27406612538066F411FC0002C02711FC000401C5600C4A02662012F8C053534166D6D9
S224FE276011FC0001C02711FC0000C0276100FF44221F4A3801C54E7511D9C053534166B6D0
S224FE278060DE48E76040720143FA08C96100FEB466387402484208380000C063660C53824D
S224FE27A066F411FC000401C56020422C00036100FECC67160C38000301C5660E0C2C005043
S224FE27C00001660651C9FFC270034CDF02064E7548E760407202103801D6B02C0003674C51
S224FE27E043F801B032BC030F42290002137801D600036100FE4E6634740248420838000091
S224FE2800C063660C538266F411FC000401C5601C6100FE6A660A197801D600034200600C4C
S224FE28206100FF60660651C9FFAE70034CDF02064E750000000000000000423801C54A2C83
S224FE284000006700010C3F077E0111FC000FC02711FC0000C02711FC0003C02743FA07F119
S224FE286011FC000EC0276100FDDA663870064A2C00046702540011C0C02711FC000AC0271A
S224FE288070FF51C8FFFE08380000C06367086100FDEC423801C56100FEEA671C0C38000341
S224FE28A001C5670451CFFFA43E1F70014E7570080838000001DB667070044840538066FCF5
S224FE28C0197CFFFF000243FA07906100FD7666D4343CFFFE1038C0510800000756CAFFF694
S224FE28E0660E11FC0002C02711FC000401C560B86100FDC066AE103801C1B02C00026708F3
S224FE29006DC41940000260BE0C000008671A0C00000967100C000010673E0C00000A662686
S224FE29207418600674206002742A0C38000201C26614397C02000006194000021942000513
S224FE29403E1F42004E7511FC000901C56000FF5A11FC000B01C54E750C38000101C266E688
S224FE2960397C01000006742060CE4A2C0000675A4281323C020082EC00064282343801DEE9
S224FE2980C4C14281122C000284C14241082C000000006604E24AE31111C101D711C201D6D2
S224FE29A0B42C00016C244842122C00029202C2EC0006B2B801E06F04223801E0520211C271
S224FE29C001D831C101DC42004E7511FC000B01C54E75423801DA600611FC000101DA225F81
S224FE29E049F801C6301F670449F801CE21DF01E021DF01E431DF01DE2F097E034A6C0006D8
S224FE2A00660001146100FE34660000EA4AB801E0670000E211FC0003C0274A3801DA672C42
S224FE2A2008380001C063670A11FC000C01C5600000C4102C0001E208B03801D66F0811FC51
S224FE2A40000DC027600611FC000CC0276100FF1C660000A26100FD7A667443F801B0303C8B
S224FE2A6009454A3801DA6602524032C0103801D7E50812C012F801D612F801D712F801D837
S224FE2A80302C0006E04812C012EC000212EC000512FC00FF43F801B06100FBA866302278A7
S224FE2AA001E44281323801DC143801DA6100FC86661C303C032051C8FFFED3B801E493B838
S224FE2AC001E082FC0200D37801DE6000FF400838000001DB663A5307671A103801C50C0018
S224FE2AE000016700FF200C00000367080C0000046600FF1A0838000001DB661470074A2CBC
S224FE2B0000046702540011C0C02711FC000BC027103801C54E750838000101DB6600FEEEFA
S224FE2B2070064A2C00046702540011C0C02711FC000AC02770044840538066FC6000FECED2
S224FE2B4011EF00040105422F0004427801CC427801D46100DB0E46FC270011FC0025C073C5
S224FE2B60423801046100D88841FA02AB6100D8A46100D87C4267307C04002F082F083F2F63
S224FE2B80000E6100FE4E6612307C04000C58424F663C0C584F5466364ED06100D852103824
S224FE2BA001C50C000004673041FA01B96100D8646100D86E41FA01CA6100D858102C000495
S224FE2BC06100D8886100D828205F548F4ED041FA01A16100D83E60DC41FA024F6100D834C7
S224FE2BE06100D9206100D8080C0000516600FF5C41FA02646100D81C60BA26484280428116
S224FE2C00468126804A93661C2681B293661C26CBB7C963EE2648B7D3660E588BB7C963F68D
S224FE2C2042804ED222006002220B201349FA015D4BFA0006600000842A0B4BFA000660001B
S224FE2C40008649FA01634BFA00066000006E2A004BFA00066000007049FA01524BFA000605
S224FE2C60600000582A014BFA00066000005A49FA01F44BFA00066000004249FA01964BFA25
S224FE2C8000066000003670014ED23E3CFFFF08380002C07356CFFFF8671411C6C0717E0EEC
S224FE2CA051CFFFFE08380002C07366024ED608780003C06551CFFFFE60F41C1C67064DFAEE
S224FE2CC0FFFA60C64ED57807E99D7C0FCC050C060009630406060007060600304DFA000432
S224FE2CE060A851CCFFE44ED5051A0522052A80020532053A056A052A052A800B0542800614
S224FE2D000552055A800E054A0562800F05420000070D0A455843455054494F4E3A20200099
S224FE2D20070D0A204E4F204D656D6F72792061743A20000D0A4C6F616420446F6E65000789
S224FE2D400D0A426164204C6F616420436861726163746572000742616420436865636B7386
S224FE2D60756D00074472697665204572726F722000074E6F7420424F4F54204469736B00EC
S224FE2D80206F6E206472697665200007424144204D656D6F7279206174200052414D20530A
S224FE2DA0697A65203D2000206973200020696E7374656164206F6620000D0A5341474520BB
S224FE2DC0537461727475702054657374205B322E345D0D0A0A436F707972696768742031A6
S224FE2DE039383320205361676520436F6D707574657220546563686E6F6C6F67790D0A4169
S224FE2E006C6C205269676874732052657365727665640D0A00426F6F74696E672066726F96
S224FE2E206D20466C6F7070790050757420696E20424F4F54206469736B20616E64207072E4
S224FE2E406573732061206B6579202851202D207175697473290007426F6F742041626F7296
S224FE2E60746564002028546573742041626F727465642900202046696C6C696E67206D6529
S224FE2E806D6F72792E2E2E0020204C6F6164696E672E2E2E00202057726974696E672E2ED6
S224FE2EA02E0020204D6F76696E67206D656D6F72792E2E2E000750524F4D20312042616431
S224FE2EC00D0A000750524F4D2032204261640D0A00427970617373656420496E69740D0AFD
S224FE2EE0004C6F6F7065642054657374730D0A0052414D207772697465206C6F6F700D0A06
S224FE2F0000426F6F74696E672066726F6D204861726420447269766500436F756C64206ECA
S224FE2F206F742066696E64200057616974696E6720666F7220447269766520526561647961
S224FE2F40203C512D71756974733E000D0A4E6F204D6174636820666F756E6400202053650B
S224FE2F6061726368696E672E2E2E000D0A4D617463682061742000202D20436F6E74696EF7
S224FE2F80756520736561726368202843203D20596573293F2000001F0027002B0033004712
S224FE2FA00052005C006A007A008F204572726F722061742000556E6B6E6F776E0042757394
S224FE2FC0004164647265737300496C6C6567616C20496E737472756374696F6E0041726990
S224FE2FE074686D657469630050726976696C656765005265736572766564205452415000A2
S224FE3000556E61737369676E6564205452415000556E61737369676E656420496E74657212
S224FE3020727570740052414D205061726974790046756E6374696F6E3A2000202041636362
S224FE30406573733A20002020496E73743A20000303D1070207000108024A00006100000CE7
S224FE3060423801C250F801BB4E7548E71C0011FC0000C50708F80000C5037080740011C028
S224FE3080C5C1723251C9FFFE7A046100004A967801F067226E1244430C4300026F18520208
S224FE30A0671C530066D860160C4300026F085202670C520060EE51CDFFD250F801BB11C090
S224FE30C001EF11FC0001C507303C174051C8FFFE4CDF00384E7511FC00B0C60711FC00008D
S224FE30E0C60511FC0000C605323C174051C9FFFE11FC0080C60776001638C605E15B1638DB
S224FE3100C605E15B444386FC000C31C301F24E75223801D67000103801B934004841B24094
S224FE31206200006E484182C04841303801B0C4C0C0C142414841944048C231C001E820382E
S224FE314001DAB4806D0C944031C201EC31C001EA600831C201EA427801ECD27801BC6530CB
S224FE3160B27801BE622A43F8020030196708B2406504524160F431C101E27000103801B85A
S224FE318082C031C101E4484131C101E642004E7511FCFFF501C34E7511FCFFF201C34E759F
S224FE31A02F02343C07D008380001C58167305342672611FC000CC5877201610001204A3878
S224FE31C001C3660000927014484008380000C58167D45380670260F270FD6000007611FC85
S224FE31E0000DC587720A610000F44A3801C3660000667014484008380000C58167065380BE
S224FE320067D660F208380001C58167CC343C07D008380001C5816728534267BC11FC000C34
S224FE3220C5877201610000B64A3801C366287014484008380000C58167D65380679A60F2EC
S224FE3240303C251C51C8FFFE4200427801C050F801C211C001C3241F4E7508380000C581BF
S224FE326066644A3801C2660A6100FF364A3801C366521038C585020000F8807801E611C0FC
S224FE3280C585323801C0927801E467326E0A444111FC000DC587600611FC000CC58761009F
S224FE32A0003C4A3801C3661C72FFE01908380000C58157C9FFF6660E31F801E401C070004F
S224FE32C011C001C34E7570FD60F61038C583020000F0803801BA11C0C5834E7548E7E000F0
S224FE32E0E349534111FC0036C60711FC00B0C607303801B211C0C601E04811C0C601741872
S224FE330051CAFFFE11C1C605E05911C1C605741851CAFFFE08B80000C503343C08EC51CA74
S224FE3320FFFE720C484111FC0080C6071038C605E1581038C605E158670C6B0A538166E68C
S224FE334011FCFFFD01C308F80000C5034CDF00074E7543F8C7C1247801DE08F80007C503D3
S224FE336011FC000FC50711FC000DC50711FC000CC5074A114A1111FC0003C78311FC004139
S224FE3380C7851011E148101131C001C4343801E8670853424A1151CAFFFC343801EA534207
S224FE33A014D151CAFFFC343801EC670853424A1151CAFFFC4A114A1108380000C78366108B
S224FE33C0303801C4B07801E2660E423801C34E7511FCFFF801C34E757400143801B880C2F7
S224FE33E031C001C011FCFFF401C34E7511FC0002C50711FC0008C50708F80006C50308B847
S224FE34000007C50311FC000DC50711FC000CC50711FC000EC50711FC0030C60711FC0070A1
S224FE3420C607303801B411C0C601E04811C0C601303801B611C0C603E04811C0C60311FCBF
S224FE3440000BC50711FC000AC50708F80001C50370FF08380004C58156C8FFF8660611FC5F
S224FE3460FFFA01C308B80001C50311FC0008C50708F80006C50311FC0005C50708F800076F
S224FE3480C50311FC000FC5074E75225F21DF01DA21DF01DE21DF01D62F096100FE2E4A385D
S224FE34A001BB66046100FBB65D8F0C38008001F56700010811FC000A01EE423801C3083837
S224FE34C00005C581660000684A3801BB66046100FB8C4AB801DA6700026A6100FC34660099
S224FE34E000546100FD764A3801C3660000486100FEFC4A3801C36600003C6100FE5666004F
S224FE350000344A3801F5670C6A0000E8423801F5610001FA7000303801EAD1B801DE91B8F7
S224FE352001DA80F801B048C0D1B801D6608611FCFFFC01C3533801EE6F00005A103801C31B
S224FE35400C00FFF967260C00FFF867200C00FFF7671A0C00FFFA67100C00FFF4660001E404
S224FE35600C38000301EE6C04423801C2303CFFFF51C8FFFE523801FF103801FF0200001FF2
S224FE3580670A0C38000501EE6600FF306100FADC6000FF284A3801F567186A00011C423834
S224FE35A001F5102F000011C001EF11C0C5C1600001920C00FFF86600018A11FC000101F5D0
S224FE35C01F7801EF000011FC000A01EF11F801EFC5C1422F00021F7C000100011F7C00022E
S224FE35E00003423801EE303C257F51C8FFFE6000FECA102F00010C0000016700007A0C00D4
S224FE3600000367000086102F00026604502F000352001F4000020C0000056D00009C0C2F82
S224FE362000020001671E103801EF1F400005902F00046500006AE208D02F000411C001EF23
S224FE3640600000621F7801EF000411FC00F501EF1F7C00030001303C257F51C8FFFE1F7CC8
S224FE366000020003422F000211F801EFC5C1423801EE6000FE460438000F01EF6404423826
S224FE368001EF1F7C0002000160D40638000F01EF640450F801EF1F7C0004000160C011EFC8
S224FE36A0000001EF11F801EFC5C150F801F511FC000A01EE6000FDFE532F0003670E423885
S224FE36C001EE11F801EFC5C16000FDF0422F00021F7C00020003102F00010C0000026D223C
S224FE36E067180C0000036708533801EF67B060CE0438000A01EF65A660C4523801EF659E28
S224FE370060BC0638000A01EF659460B248E75000303C258051C8FFFE11FC0000C507705008
S224FE372051C8FFFE6100F9B031F801F201F011FC0001C507303C257F51C8FFFE4CDF000A24
S224FE37404E751038C583020000F011C0C5835C8F103801C34E75225F261F321F700003C004
S224FE376011C001BAE90911C101F42F09423801BB11FC000101B811FC001301B931FC0200C3
S224FE378001B031FC004001B431FC004801B631FC177001B242780200427801BC427801BE14
S224FE37A06100FB28722F484108380005C581673441FAF7776100CC5C6100CC3460080838F7
S224FE37C00005C581671E6100CD32670A6100CD340C0000516704538166E411FCFFFC01C331
S224FE37E0600000DE70FF08380005C58156C8FFF86700001248410C41002F57C048414A0011
S224FE380066AE60BA223C00000000722F484108380000C58167146100CCE2670A6100CCE45D
S224FE38200C00005167B4538166E442A741F804002F08203C000004002F006100FC4E6600F2
S224FE384000807010B6806D2E204343F8060076002211B290660A22290004B2A8000467166B
S224FE3860D2FC00205243B67C00106DE411FC000101C36000004C873801F4E54B41F8040090
S224FE388031F0300001BC31F0300201BE11E801F601B911E801F701B831E801F801B031E8D5
S224FE38A001FA01B431E801FC01B631E801FE01B2D0FC004043F80200701F22D851C8FFFCD7
S224FE38C01038C583020000F011C0C583103801C34E752C5F11EF0004010508F800010105DF
S224FE38E0422F00046100CD7C46FC270011FC0025C073423801046100CAF641FAF6056100A1
S224FE3900CB126100CAEA6100FE4E665242A7307C04002F082F086100FB72661C307C040046
S224FE39200C58424F662E0C584F5466287000103801F43F002F0E4ED06100CAB4103801C334
S224FE3940440041FAF41F6100CACA6100CAD46100CA9E4ED641FAF41B6100CAB860F00C3830
S224FE3960000101C366D26100CA8641FAF5AD6100CAA241F801F66100CA9A60D2FFFFFFFFC9
S224FE3980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
S224FE39A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
S224FE39C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
S224FE39E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
S224FE3A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
S224FE3A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
S224FE3A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
S224FE3A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
S224FE3A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
S224FE3AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
S224FE3AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
S224FE3AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
S224FE3B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
S224FE3B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
S224FE3B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
S224FE3B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
S224FE3B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
S224FE3BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
S224FE3BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
S224FE3BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
S224FE3C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
S224FE3C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
S224FE3C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
S224FE3C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
S224FE3C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
S224FE3CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
S224FE3CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
S224FE3CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
S224FE3D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
S224FE3D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
S224FE3D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
S224FE3D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
S224FE3D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
S224FE3DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
S224FE3DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
S224FE3DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
S224FE3E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
S224FE3E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
S224FE3E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
S224FE3E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
S224FE3E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
S224FE3EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
S224FE3EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
S224FE3EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
S224FE3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
S224FE3F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
S224FE3F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
S224FE3F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
S224FE3F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
S224FE3FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
S224FE3FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
S224FE3FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
S804FE0000FD

514
SAGE/FILES/v2-2.hex Normal file
View file

@ -0,0 +1,514 @@
S00B000076322D322E68657885
S224FE00000000040000FE0044600004F2600004E66000095E60000448600003F2600003CA02
S224FE0020600003F8600003FE600029A2600029A460000334F1940202600002F66000343C61
S224FE0040600035364E704FF8040011FC0092C02711FC0038C02511FC0092C06711FC003115
S224FE0060C065700072FF343C42D741F8C0FE3080308151CAFFFA43F8000045F87FFE343C1D
S224FE0080344230113010301251CAFFF8343C06C541F8C00172084A10D0FC001051C9FFF81C
S224FE00A051CAFFEE43FA0006600002C049FA2D054BFA000660002BFE41FA00362278000874
S224FE00C021C80008B1F80008662E11FC0090C58711FC0090C50711FC0000C58311FC00CD66
S224FE00E0C50311FC0000C58511FC0005C50560044FF8040021C900081038C0216B64E6087B
S224FE010002400006303B00064EFB000200180024001800084238010449FA2DB14BFA08523D
S224FE012060002B9249FA2DB54BFA003860002B8649FA2DB84BFA000660002B7A74FF72008F
S224FE014070001038C023460008000002670272FFE308024000064840204030C151CAFFFCB5
S224FE016060DA41FAFE9C343C1FFF42004201D018D21851CAFFFA4A00671449FA2D334BFAC7
S224FE0180000660002B304A38C0216A0001004A01671449FA2D294BFA000660002B184A38FE
S224FE01A0C0216A0000E811FC0001C067307C000072014841323CFFFE224145FA00066000B9
S224FE01C02A34664647FA000C21CB000808F80002C5034FF8040047FA002421CB00087202EF
S224FE01E04841D3C1303CA5A53280B051660E46403280B05166064640D3C160EC4FF80400AC
S224FE020093C145FA0006600029EC67084A38C0216A00007A303C00BF41F80100429851C8BF
S224FE0220FFFC548921C901004E6121C9014A21C9014243FA000C21C9000808B80002C50322
S224FE02404FF804006100041611FC0000C0674A38C0216B1611FC0007C06770FF51C8FFFEFD
S224FE026011FC0006C0676000FEFA6100017C41FA2B256100019830380100ED48610002166F
S224FE0280704B610001DA6100016060044E7227007228740208380006C0216702725011C222
S224FE02A001C611C101C7423801CA11C201CE11C101CF11FC000101D27206610000F8423825
S224FE02C001BA2278000841FA002A21C8000811FC00AAC58311FC0005C5050C3800AAC58357
S224FE02E0661011FC0000C58350F801BA31FC023001F04FF8040021C900081038C021C07C3B
S224FE03000030670CB07C00206724B07C0010672621F80100014A21F80100014231FC270081
S224FE0320014E41FA004221C801466000064442676100280860DA4A3801BA67D420380100CF
S224FE03404840720C92406F12C2FC000A5341303C6F9A51C8FFFE51C9FFF6426770012F0002
S224FE03606100338460AA4E4F60FC41F8C0734200108011FC0076C007E01810801238C02124
S224FE0380E0181080706E080100036702707E10BC00400241000711FB1014C003108011FCAB
S224FE03A00000C003E01810BC00254ED1028040201008040241F8C0334240108011FC00B66E
S224FE03C0C007E018108011FB10E4C005E018108011C0C005E01810BC0040E01810BC004ED2
S224FE03E0E01810BC00274E752F00700D6170700A616C420061686166616461626160201F2E
S224FE04004E752F0070206156201F4E753F0010186704614A60F8301F4E75E9186126E9182E
S224FE042061224E752F017203E958611851C9FFFA221F4E752F017207E998610851C9FFFA57
S224FE0440221F4E753F000200000FB03C0009630406000007060000306104301F4E754A38AD
S224FE04600104662C3F01323CFFFF08380002C07356C9FFF8670811C0C071321F4E7548E7F7
S224FE0480C0C043FA00066000FEE24CDF030360D64E4A4E7548E7F000720032007400343CED
S224FE04A02710420382C266044A0367061001619450C34241484184FC000A66E84CDF000F1E
S224FE04C04E754A38010466282F011238C0730801000167F61038C071020100386604221FCE
S224FE04E04E7511FC0035C07370076100FF7260DA4E494E7508380001C0734E7561C4088000
S224FE050000070C0000616D0A0C00007A6E04088000054E7521C001067002604E21C00106B5
S224FE05207004604621C001067006603E21C001067008603621C00106700A602E21C00106D4
S224FE0540700C602621C00106700E601E21C001067010601621C001067012600E21C0010614
S224FE05607014600621C00106701648F87FFE010A4E6821C8014A2A007016BA806270BA3CBC
S224FE058000046206381F261F341F31DF014E21DF014621CF01424FF804000C05001467004D
S224FE05A0199A6E0018B80C050012661E11FC0001C06711FC0000C0674A3801BA670C08F887
S224FE05C00002C50308B80002C50370FFE01851C8FFFC46FC270011FC0038C02508B80006F0
S224FE05E001504238010443FA000A6000FD7E428560A849FA27164BFA0006600026B849FAEB
S224FE06002990D8F450004BFA000460EE49FA29964BFA000460E420380146610017F661006E
S224FE0620FDC80C0500046200034841FA29FE6100FDDC30046100FDEE41FA29FB6100FDCE89
S224FE064020036100FDF041FA29F86100FDC030026100FDD26100FD926000031641F80008A0
S224FE066043FA268045FAF99A4280301967186B06D08A20C060F2424112003019D08A20C023
S224FE068051C9FFFC60E24E75225F02800000000FD080D089C1893251D3C04ED148E780B0A4
S224FE06A02478000847FA001421CB0008101121CA00084CDF0D01B0004E75508F321F46C153
S224FE06C041FA26586100FD46588F20096100174421CA00084CDF0D01000000014E750838BE
S224FE06E00001C0734E752F00703A6100FD72201F6100FD104E752F00702C6100FD62201F1D
S224FE07004E752F0070076100FD56201F4E75C03C007F0C0000206D060C00007E6D02702E06
S224FE07204E752F092F01224842816100FDD00C00001B6700006E0C000012670000680C003B
S224FE0740000D674A0C000008661AB3C867DC6100FD0E6100FCAE6100FD0651C9FFF25389C4
S224FE0760528260C40C00007F6614B3C867BC61585389528210116100FCE6544160AC611AF2
S224FE0780428153826B0812C06100FCD4609C610A421912C0221F225F4E758281673C4281C6
S224FE07A0602C224842812F0870236100FCB26100FC38B3C86700000C10186100FCA2B3C87F
S224FE07C066F6205F6000FF648281660E72013F00103C005C6100FC88301F4E7542801018C6
S224FE07E08000660253884E7561F28000670A0C00002067040C00002C4E7561E067080C00DE
S224FE0800002067F653884E7561D2244942411219B011568957C9FFFA660001481021E1589A
S224FE08201021D4C04ED248E7180042817801E89C61B667540C00002F660E383C33334844E2
S224FE0840383C333461A26740040000306D380C0000096F144A04662E040000070C00000A9C
S224FE08606D240C00000F6E1E26014A046708E799E39BD2836002E999B684640AD280848222
S224FE088067C2B48164BE72FFC1414CDF00184E752F036100FF66428395CA6100FF4C67002D
S224FE08A000480C00002367360C0000246708347801525388602A6100FF306700002C0400F7
S224FE08C0003065240C000003641E244093C96100FF18670000180C00002B660C6002528334
S224FE08E042826100FF42670257832240D5CAD5CAD4FC0154D3D2201FC14380804E752F02AB
S224FE090042826100FEF6670000520C000027671C0C00002E674624016100FF0C6B06241F20
S224FE092092814E75241F428153814E756100FEAE6100FEAA670000200C0000276712E19A7D
S224FE09404A0266E0D480828167E6B28264E260D46100FE9666CEC14260C47001241F22008A
S224FE09604E756100FA9E703F6100FAF46100FD944FF8040042B801546100FA6E083800061F
S224FE098001506700000870546100FAD436380152670C70246100FAC810036100FAA8703EF2
S224FE09A06100FABC742841F801886100FD7643FA1A686100FE5460B843FA1A8C6000FE4AD6
S224FE09C06100FE382838017E387801821010670E6100FEBE668C2809284A31CA0182610045
S224FE09E0FE1A327C01001010670A6100FEA46B00FF726704D3C45389528921C9017E2A0968
S224FE0A00611C6718280B6100FCD667F46100FAEE0C00001367F60C00000366E44E756100D4
S224FE0A20F9C820046100FA0EB8FC0154670C6100F9D2200490946100F9FC6100FCAA760F93
S224FE0A402644C7496100FC56C7496600FF16101B6100F9C808030000660000066100F9A419
S224FE0A60BA8B57CBFFDE6100F99A760F2644101B6100FC9C6100F9E8BA8B57CBFFF24E75CB
S224FE0A8043F80154323C20247402601443F80126323C2041600843F80106323C20447407FF
S224FE0AA06100FD3A671A903C00306B00FEB678001800B8026E00FEAC61226100F92C4E75D1
S224FE0AC04284611852846100F93A0C04000466046100F9306130B8026DEA4E756100F90A99
S224FE0AE042833001E0880C000020670000066100F96E10016100F968868366061004610077
S224FE0B00F9446100FBE22004E5800280000000FF4A836A42303100006100F90A0C4153521D
S224FE0B20663C48E7704036006100F8D870286100F92E428243FA18D21419670E1019E57B94
S224FE0B40650270206100F91860EE4CDF020E70296100F90C6008203100006100F8D84E75F4
S224FE0B606100FC7A6600FDFC6100FF226100FF28611861086148610461344E756100F8840D
S224FE0B806100F8804E756000F86061FA103C00506100F8CC103C00436100F8C46100FB4892
S224FE0BA020380146307801526000126861D876FF43F8014E223C00005352600E61C843F8B1
S224FE0BC0014A223C00005553760142846100FF144E757C0060000C2C700072104A10670A7C
S224FE0BE06100FC446B00FD7C12006100000E5200B0016DF66100F7F24E756100F7EC41FAFA
S224FE0C0000206100F8086100F83C41FA001B3438017C0102670441FA001B6100F7F04E75AD
S224FE0C205452415020230020204E6F2074726163652000202054726163652020202000003C
S224FE0C4043FA18A26000FBC26100FCB46600FD142A006100FCAA6600FD0A2800D085610079
S224FE0C60F7882200103C002B614822059284103C002D613E2205C2C4103C002A61344A4415
S224FE0C806746220582C4103C002F61186132103C00726100F7CA103C00656100F7C2103CB9
S224FE0CA0006D48416100F7B86100FA3C30016000F7746100F7AA6100FA2E20016100F7761E
S224FE0CC06100F7406000F73C4E757C106100FB2C2838017E38780182101067106100FBB258
S224FE0CE06600FC802809284A31CA01826100FB0C327C00141010670C7CFF6100FB946B005B
S224FE0D00FC6267062C096B00FC5A52892A092C446100F6D6200E6100F71CB8FC0154670C46
S224FE0D206100F6E0200E90946100F70A6100F9B848E7060061304CDF006021CE017E4A8624
S224FE0D406B065386671E2A0EBA8E650000186100F98E67BC6100F7A60C00001367F60C0033
S224FE0D60000366AC4E75300EE2086500FBF67C07610006F03E00E9586100F90E0020010038
S224FE0D8001080104014003880428046E0512060606CC053A05A60606065206CC08070008AC
S224FE0DA0664E43FA176C3207E049E249610006F659016F5E0401001067585801660642458B
S224FE0DC0611C60063A07610006C4610006FC6100070216076100F920610007364E75428535
S224FE0DE043FA171E3207EC5902410003600006B63007020000380C00000867367042610069
S224FE0E0006AE61DA610006C23607EC5B6100072860C030070200003F0C00003C66A64282F3
S224FE0E20263A084C080700066704263A0846600000F2203A082A610006767050610006707B
S224FE0E403A07E35D08C500066100064E6100067A08070007670A61126100F89C61144E757E
S224FE0E6061106100F89261024E753607EC5B600006C6360708C30005600006964285600607
S224FE0E807A4060027AFF203A07D6610006223007EC5802000007530066067041610006108F
S224FE0EA0610005F6610006223607610006646100F8463607EC5B610006644E75080700087A
S224FE0EC0660002043007EF580240000732006100F7B8001000320014001C007C011800B2E1
S224FE0EE001527401600A263A0786428260064282263A0780283A07683007020000C00C0025
S224FE0F0000C0671843FA16366100059A3A076100057C610005B4610005F64E752004610025
S224FE0F20058E7A40610005A228034A026614610005DE4A84670A6100F7BE200461000570D5
S224FE0F404E7561F66100F7B0610005C44E753207E65902410007080700076624203A0718A4
S224FE0F6008070006670C203A07124A016604203A070E6100053A61000550610005924E753E
S224FE0F804A016756203A06D861000524704D3A07E35D08C5000661000516610004FC610035
S224FE0FA005287A40610004BC31C001880807000A661E6100000C6100F73E610005524E7591
S224FE0FC070236100F49A303801886100F4584E7561E86100F72261E84E75203A06AA080743
S224FE0FE00006678E203A069C60880C0700FC6612203A0698610004B8203A0694610004B06A
S224FE10004E753A07024500C00C4500C0670A3005E2588A406000FEEE283A06784282428352
S224FE10206000FED608070007660000983207E6590201000714010C01000667520C010003F2
S224FE10406F14263A065E024200010247000F004700C86000FEA043FA14FC61000448610041
S224FE10600468E20A660E70236100F3F430076100F3D44E753607E75B610004C008070003EE
S224FE1080660A6100F6727A40610004484E75320702410007340143FA14CC610004080C029A
S224FE10A00002660A610004227A406100042670544A02670870560C02000666046100F3A038
S224FE10C04E754280600270023207EC59C27C0001D2407A4043FA14AE610003CA610003EAB0
S224FE10E06100042C0807000867186100F60A3607EF5B70200807000667027028B1436100E3
S224FE110004104E753207020100C00C0100C0673E203A0588080700086704203A05826100DC
S224FE1120038E3A07610003666100039E70236100F32E3007EF58020000074A006602700848
S224FE11406100F3026100F5B0610003C44E7570533807020400380C040008660808870003ED
S224FE1160303C4442611C610003A60C04000866106100F5847A40610003603440610003FA3B
S224FE11804E7543FA1440610003263207EE5902810000001ED3C142803011610003126100DF
S224FE11A003284E757A40320702410F000C410100670A704243FA13EE61CC600C203A04D87B
S224FE11C0610002EC6100030230074A0067106100F24AE158E040548E6108558E4E75610017
S224FE11E002F83440610003924E750807000866000258203A046A610002B67051610002B039
S224FE1200610002C670236100F25610076100F20C6100F4E43607EC5B6100031C4E753A07AF
S224FE122043FA13C2612208070008670C61106100F4C6610002DA4E7561F86100F4BA36075B
S224FE1240EC5B610002F24E753207E95902410007610002524A456704610002326100026A56
S224FE12604E75428560023A0743FA139A61DA3607E75B61086100F4803607EC5B08070003C6
S224FE12806606610002B24E75610002C04E753007024001F00C40010067C8EC4872045740FA
S224FE12A0670859406600FF787205088700068E7C41006000FE1E3007EC580240000755401A
S224FE12C06F00FF5C43FA133E7A4053406706E35D594066166100FF72610002346100F418CE
S224FE12E03607EC5B610002544E75044710003007024000380C4000086600FF24203A03A8FF
S224FE1300610001AC3A0761000184610001BC3607E75B61086100F3E03607EC5B610002264E
S224FE13204E753007024001F878000C400140671078030C400148670878020C4001886624A1
S224FE1340203A0368610001686100017E3607EC5B61086100F3A23607E75BE21C650001DC79
S224FE1360600001D4E8480C0000106700FEF67206E44857406700FF347207594067F66000EA
S224FE1380FE9E3007024000C00C4000C067123007024001300C4001006700FECC6000FE80EA
S224FE13A03A07E25D43FA12563207E55902410001610000F2610000E26100010E6100015092
S224FE13C06100F3343607EC5B610001704E7532073A07024500C00C4500C06744E65961503C
S224FE13E0610000AA610000E2360702430E00080700056708EC5B6100013E60167023610038
S224FE1400F05E3003EF580200000F660270086100F0346100F2E23607E75B6100011A4E7598
S224FE1420EF59610C4285610000A0610000E24E7502410003340702420100EC5A824243FA19
S224FE144011DC610000604E75702E61000062203A02126100005A6100007030076100EFC670
S224FE14604E752F09224E6100F2346600F4F6301E225F4E752F09224E6100F2226600F4E43A
S224FE148054896100F218201E225F4E75024500C00C05008066027AC03205EC5902010003C3
S224FE14A043FA108AE519024100FF203110002F017203E1984A00670000086100EFA253068F
S224FE14C051C9FFF0221F4E756100EF3851CEFFFA4E7570236100EF883205EC59C27C000371
S224FE14E0B23C000267206100FF7A53016C066100EF2A4E756100EF2E53016D086100FF648A
S224FE15006100EF224E75703F6100EF544E7536071003E60802000007E70B86001003024069
S224FE152000076100F164001000140018001E00240076008000C67244601472416010223A08
S224FE15400112600A223A01106004223A010E7403E1991001671C6100EF060C000044670637
S224FE15600C000041660C3003E618020000076100EED451CAFFDC4E75705B6100EEE2D5CEF4
S224FE1580200A558030780152D1C8D1C890A801546100EEA2705D6100EEC64E756100FEC4D6
S224FE15A06100EE8260986100FEBA38006100EE6C70286100EEAA61826100F13C3604EF5BCD
S224FE15C00804000F66066100FF6E60046100FF6C702E6100EE8A70570804000B6702704C09
S224FE15E06100EE7C70296100EE764E75E61BC63C000710036100F0920012001C0026003E6A
S224FE160000540010001000104E756100FE566100EE144E756100FE5E6100EE1A4E7561005B
S224FE1620FE4234406100EDFE223A003C6100FF206100FF464E756100FE2A38006100EDDC3B
S224FE1640203A00286100FE686000FF6E6100FE844E75284129002841292B2D2841294D4F21
S224FE16605645574F5244285043292850430043435200535200004E424344504541005357DD
S224FE168041504558544C45585457494C4C4547414C005441530042535200414444515355A6
S224FE16A0425155535000434D504D4558470043FA0DB56000F1546100F1D86600F2A660045B
S224FE16C06100F0402809284A2A0454856100F3506100F01441F80188243C00000028610018
S224FE16E0F042428110106716223C0000FFFF6100F20E6BCC6E0A13400001E08012805489C6
S224FE17000C01002E66BE4E7543F80154323C202474037A01601643F80126323C2041600861
S224FE172043F80106323C2044740842856100F0AE671A903C00306B00F22AB0056B00F22416
S224FE1740B0026C00F21E4282610E4E75200561085280B0026DF84E7542832F023A012800CF
S224FE17602C00E5864A82660E6100F0904A10662260046100EF8E32056100EC6E6100F364E0
S224FE17806100EF64742841F801886100EF961010672042816100F1686BD8660000160286E3
S224FE17A0000000FF86836A063380600060042380600032051004241F4E756100F02066000C
S224FE17C0F1A26100FF526100FF586106611E610E4E7543F80146323C50436000001843F8BB
S224FE17E0014E323C535276FF6000000C43F8014A323C55537601428242806100FF5E4E7589
S224FE18007CFF7A0142806100EFD467144486903C00306B00F14EB03C00016E00F1463A0032
S224FE1820360060046100EEDC3643D7CB284BD7CB4A866B0A675A6100EFC24A106614616AF9
S224FE18406100EEA4742841F801886100EED66100EFAA101067320C00002E660607B80150A6
S224FE186060266100F02C6BBC6100EF90243C0000FFFF6100EFB26BAC426C017239400176D3
S224FE188007F80150274901605243B6456F9A4E75611860F4427265616B706F696E742000CC
S224FE18A0496E61637469766500006100EB3C41FAFFE46100EB5810036100EB8A6100EE2848
S224FE18C007380150660A41FAFFD86100EB404E75202B01606100EB5E6100EB2870286100E1
S224FE18E0EB7E302C01766100EB3C6100EE0A302C01726100EB3070296100EB644E757600FB
S224FE190078104A10671C6100EF1E6B00F056160018006100EEE60C00005467460C00004E76
S224FE192067386100EAC441FA004C6100EAE010036100F2C86100EDB0742841F80188610059
S224FE1940EDE26100EEB667240C00005467140C00004E67066100EDAC60C83238017C0781F2
S224FE196060063238017C07C131C1017C5203B6046DBC4E7528542972616365206F7220285C
S224FE19804E296F2074726163650043FA0AF86000EE78243C000000FF616C6600EFC61A00C9
S224FE19A0E1401005600C243C0000FFFF61586600EFB23A0048403005600842826148660032
S224FE19C0EFA241FA14AA6100EA4461000942E19812C0538466F821CA00084E7548E7F000EA
S224FE19E06100EEAE661A28096100EEA62449C9896B0E6E06988952846004D5C9538A4280FD
S224FE1A004CDF000F4E7561D4660622026100EEF04E7561F266142C0098876D00EF4670FFD6
S224FE1A204A10670A22026100EED66600EF3641FA15266100E9D8610008D64E7543FA0AB46F
S224FE1A406000EDC6243C000000FF7E0161C41219C200B206670453846CF46100009660F6D9
S224FE1A60243C0000FFFF7E0261A81219E1991211C240B246670453846CF06100007660F6EF
S224FE1A8042827E04618C2649548B1219E1991211E199121BE1991213C280B28667045384F8
S224FE1AA06CE86100004E60F66100FF326600EEB448E708606100FF266600EEA82A492C0474
S224FE1AC04CDF0610C34D41FA148E6100E9406100083E9C846518284952892E04264D121CE8
S224FE1AE0B21B6606538766F6610853866CE861024E7148E7FE7E663E41FA146B6100E90E5B
S224FE1B00538920096100030C6100EBDC7203E198101951C9FFFA6100E91C41FA1455610090
S224FE1B20E8EC6100E9D80C00004366126100E9304CDF7E7F4E7541FA140D6100E8D04CDFE0
S224FE1B407E7F21CA00086000EE286100E8B66100E8B243FA093A6000ECB043FA093C6000C4
S224FE1B60ECA86100ED2C6600EDFA20096100E8C66100EB7410116100E8A24E756100ED12E0
S224FE1B806600EDE03C09080600006600EDD620096100E8A26100EB5030116100E8884E750E
S224FE1BA043FA08FD6000EC626100ECE66600EDB4223C000000FF6100ED466600EDA612807C
S224FE1BC04E756100ECCC6600ED9A3C09080600006600ED90223C0000FFFF6100ED226600D1
S224FE1BE0ED8232804E756100EC1274076100EC386B00ED7022006000E7BC43FA08AA600063
S224FE1C00EC086100006443FA07B654894A516700ED523014C059B05966F0D8D121CC016835
S224FE1C2008F80002015008F800040150600261387401610001BA426A017251CAFFF66002DC
S224FE1C40612608B80005015008F80006015008F8000701501038015002000007660608B867
S224FE1C6000060150600001506100EB901010670C6100EC1E6600ECEC21C901466106610048
S224FE1C80E7684E752C380146284608060000671241FA001C6100E77620066100017660001C
S224FE1CA0ECD0224C6100E9F66600ECB84E75496C6C6567616C2070726F6772616D20737411
S224FE1CC061727420616464726573733A20006100E71843FA07DC6000EB30083800060150C8
S224FE1CE0670461A0604E4E7508F8000501506040619208B8000301500C100049660808F834
S224FE1D000003015052887005083800050150660270104A10670E747F6100EAE06100EB085E
S224FE1D206B00EC406100E6C2600C08B8000501506100FF36700111C0015108F800060150FD
S224FE1D4008B80007015030140240FFF00C404E406664301C0240000F3C38017C41FA002C5A
S224FE1D600106661C21CC016808F80007015008F80002015008B800040150673A41FA0021C4
S224FE1D806100E68A6100E662602C2A2A2A2054726163696E672054524150202A2A2A002AB5
S224FE1DA02A2A204753207465726D696E61746564202A2A2A0000287801463C38014E08383D
S224FE1DC00006015066060886000F600408C6000F2078014A4E602E7801422F0C3F064CF821
S224FE1DE07FFF01064E7308B8000601504E7542803242D3C92449D3C905380150670E226957
S224FE1E0001606100E8986600000652804E7553804E756100E62030780152D0C8D0C84A7892
S224FE1E200152672E6100E5DC2F0070286100E63070246100E62A303801526100E6086100E7
S224FE1E40E8A6201F90A801546100E5EA70296100E60E4E7554726163653A200008380006B5
S224FE1E6001506700FF52083800070150672608B80006015074006100FF766B00EAE6670826
S224FE1E803551016C32BC4E4F52420C42000366E66000FF2441FAFFBE2038014621C0017E16
S224FE1EA06100E56A28406100FF6AD0FC015431C801826100E832224C6100E7E266143011D2
S224FE1EC06100E5626100E53C6100E5382C496100EE96083800050150670A41F801884210E2
S224FE1EE06100EC7E533801516F1E083800030150671A6100E7EA67146100E6020C00001380
S224FE1F0067F60C00000366046000EA666100E4DA6000FE280D0A556E657870656374656467
S224FE1F2020627265616B20706F696E743A2000000D0A427265616B3A200042854286283890
S224FE1F4001465584760041FAFFCC74026100FEA06F32B3C4661E41FAFFD876020C02000237
S224FE1F6067123A2A01723C2A0176BC4567065245354501720C514E4F670605B80150600466
S224FE1F8032AA016C51CAFFC60838000201506728B8B80168662208B80002015008B80004BB
S224FE1FA00150661421C4014608F80006015008B8000701506000FEA620380146908321C021
S224FE1FC00146BC456600FC824A436600FED028440C544E4F6600FEC620046000FEC043FAFF
S224FE1FE004E46000E82411FC000101BB6004423801BB41FA0E8E6100E414607642857401E4
S224FE20006100E8246B00E95C3C00243C0000FFFF6100E8146B00E94C3F006100E8746600A7
S224FE2020E9422F0942826100E7FE6B00E9362F003F064A85670E41FA0E576100E3D06100D9
S224FE20400992600C41FA0E3C6100E3C26100097E6700000E41FA000C6100E3B26100E3BC51
S224FE20604E750D0A4469736B206572726F723A20000061740C000051670000C00C0000539C
S224FE208066F0420561621E00610000BC1C0153064281610000B2610000AE26410C0700309D
S224FE20A0660E4A0667066100009E60F6617460C20C0700326614220B6100008C26414A0610
S224FE20C067EA6100008216C160F40C07003167EE0C07003966644A066660614641FA0C4F9C
S224FE20E06100E32A6000E88A4A3801BB672408380001C033670A1038C031088000074E75A4
S224FE21006100E3F267E26100E3F40C00005166D84E756100E3AE0C00000D6700E2CC600027
S224FE2120E33E6122460566024E75588F41FA0C216100E2DA6000E83A508F41FA0BFD610011
S224FE2140E2CC6000E82C61086106DA0153064E7561960C0000306DE00C0000396E0A040052
S224FE21600030E989D2004E750C0000416DCA0C0000466EC45F0060E643FA03436000E68A25
S224FE21807A016000FE7A6000E7E843FA03426000E678202053797374656D207265696E697E
S224FE21A07469616C697A696E672E2E2E2E0046FC270011FC0025C0734238010441FAFFD43E
S224FE21C06100E24A70FF51C8FFFE6000DE784280428710100C00005266063E3C010052886A
S224FE21E01010670A74016100E63E6B00E77680473F00610009464E754A3801BA6700E76421
S224FE2200428042877C0110100C00005266063E3C010052881010675C0C00002067140400E6
S224FE222000306D00E73E0C0000036E00E7368E0052886100E5C64A00673A0C00002366004B
S224FE2240001652884A10672C740F6100E5DA6B00E7123C00601E740743F801F62C09429128
S224FE226042A90004422900086100E572670612C051CAFFF63F072F066100146C4E754E7510
S224FE228074186100E16451CAFFFA4E7543FAE2D621C9002443FAE2C621C900BC4E7542801F
S224FE22A01010670A74026100E57E6B00E6B631C00152E540D07C015431C001824E756100A7
S224FE22C0E5D06600E69E28096100E5C66B00E694C98966049889600253846500E6862649E4
S224FE22E06100E5AE6600E67C41FA0BB26100E11E7201B7C96406D3C4D7C472FF61101293B1
S224FE2300D3C1D7C153846CF621CA00084E752478000849FA000821CC00084E7541FA09FCB8
S224FE23206100E0EA548F201F6100FAE821CA00086000E63E43FA01B56000E4CE3F3C000112
S224FE23406002426774016100E4DE6B00E6163F00243C0000FFFF6100E4CE6B00E6063F002A
S224FE2360427801CC427801D411FC000101DB3F172F3C000004002F3C000010003F2F000CA0
S224FE23804A6F001067066100064A60046100063E662A702E6100E0C808F8000101DB6100D5
S224FE23A0E15467CA6100E11C11FC0007C02711FC0009C027423801DB5C8F4E75705860D45E
S224FE23C0F0FF60000004F00060000002F0F850C80004FFB84E900002FFB84EA80004FFB852
S224FE23E04EB00004FFBF4EB80004FFBF4EB90006FFBF4EBA0004FFBF4EBB0004FFF04E4033
S224FE24000002000000000000015402530958014E015A0156014300000E44A0E55396F2466F
S224FE242072F52486FE4DA6FE5032F754B6F847E2F75760FD4CC6FB00C2F84972FD4128E87A
S224FE2440451CFF5824F6094D7AE5521AE74450E64146E65044E75366E75576E7243AE64265
S224FE24608CE75492E7094D51F25255F344BBF241B1F2506DF35379F35587F324A3F2429B3D
S224FE2480F35499F402420EF55722F54C36F50249CCF64F12F75358F70142CAF657E4F601FD
S224FE24A04209F75723F7024F88F7439AF7535CF703427AF84536F95238F84E40F80141C9DE
S224FE24C0FC46C3FC024122FB542AFB4638FB064600FD482AFD47B0FD53E0FC568EE143B211
S224FE24E0FD54BEFD0144E6E75264E7015257FE5751FE034252F5576EF54C8EF54DB6F500C3
S224FE25005453540043484700434C5200534554004F524900414E44495355424941444449D3
S224FE252042000000454F5249434D50492E4200002E5700002E3F00002E4C00004E454758F0
S224FE2540434C52004E4547004E4F5400000000005453540054524150545241504C494E4B35
S224FE2560554E4C4B524553454E4F500053544F5052544500344537345254530054524150BD
S224FE2580525452004A5352004A4D500043484B004C45410044495655444956534D554C5511
S224FE25A04D554C535241460048494C53434343534E45455156435653504C4D4947454C54E9
S224FE25C047544C455400460048494C53434343534E45455156435653504C4D4947454C541D
S224FE25E047544C454F52000053554200454F5200434D5000414E4400414444005355424194
S224FE260041444441534243445355425800000000434D50414142434441444458415352001D
S224FE26204C535200524F5852524F520041534C004C534C00524F584C524F4C0048E760409C
S224FE26401219143C00AD1038C0510800000756CAFFF6671A08000006661411D9C05374094F
S224FE266051CAFFFE530166DA4CDF02064E7511FC000101C560F248E7604043FA09D461BC89
S224FE26806624720243F801C36174661A123801C3020100C0670C0801000667047203600250
S224FE26A0720211C101C54CDF02064E7548E76040720743F801BC42116144663C123801BC34
S224FE26C0020100C0672E0801000667267205103801BDE208651E7206E40865187207E408D3
S224FE26E065127208E208650C7209E4086506720A6002720211C101C54CDF02064E75343C69
S224FE270010FE1038C0510800000756CAFFF6671608000006671012F8C053740951CAFFFE77
S224FE2720530166DA4E7511FC000101C54E752F017002484008380000C0636612538066F476
S224FE274011FC0002C02711FC000401C5600C4A02662012F8C053534166D611FC0001C02789
S224FE276011FC0000C0276100FF44221F4A3801C54E7511D9C053534166B660DE48E76040B8
S224FE2780720143FA08C96100FEB466387402484208380000C063660C538266F411FC0004EF
S224FE27A001C56020422C00036100FECC67160C38000301C5660E0C2C00500001660651C927
S224FE27C0FFC270034CDF02064E7548E760407202103801D6B02C0003674C43F801B032BCFE
S224FE27E0030F42290002137801D600036100FE4E66347402484208380000C063660C538201
S224FE280066F411FC000401C5601C6100FE6A660A197801D600034200600C6100FF6066068A
S224FE282051C9FFAE70034CDF02064E750000000000000000423801C54A2C00006700010C3B
S224FE28403F077E0111FC000FC02711FC0000C02711FC0003C02743FA07F111FC000EC0278B
S224FE28606100FDDA663870064A2C00046702540011C0C02711FC000AC02770FF51C8FFFE97
S224FE288008380000C06367086100FDEC423801C56100FEEA671C0C38000301C5670451CF75
S224FE28A0FFA43E1F70014E7570080838000001DB667070044840538066FC197CFFFF0002B1
S224FE28C043FA07906100FD7666D4343CFFFE1038C0510800000756CAFFF6660E11FC0002A6
S224FE28E0C02711FC000401C560B86100FDC066AE103801C1B02C000267086DC419400002EA
S224FE290060BE0C000008671A0C00000967100C000010673E0C00000A66267418600674208C
S224FE29206002742A0C38000201C26614397C0200000619400002194200053E1F42004E7537
S224FE294011FC000901C56000FF5A11FC000B01C54E750C38000101C266E6397C010000062E
S224FE2960742060CE4A2C0000675A4281323C020082EC00064282343801DEC4C14281122C1F
S224FE2980000284C14241082C000000006604E24AE31111C101D711C201D6B42C00016C24E7
S224FE29A04842122C00029202C2EC0006B2B801E06F04223801E0520211C201D831C101DC3A
S224FE29C042004E7511FC000B01C54E75423801DA600611FC000101DA225F49F801C6301FD2
S224FE29E0670449F801CE21DF01E021DF01E431DF01DE2F097E034A6C000666000114610053
S224FE2A00FE34660000EA4AB801E0670000E211FC0003C0274A3801DA672C08380001C063BA
S224FE2A20670A11FC000C01C5600000C4102C0001E208B03801D66F0811FC000DC02760065B
S224FE2A4011FC000CC0276100FF1C660000A26100FD7A667443F801B0303C09454A3801DA3A
S224FE2A606602524032C0103801D7E50812C012F801D612F801D712F801D8302C0006E04858
S224FE2A8012C012EC000212EC000512FC00FF43F801B06100FBA86630227801E4428132381F
S224FE2AA001DC143801DA6100FC86661C303C032051C8FFFED3B801E493B801E082FC0200E9
S224FE2AC0D37801DE6000FF400838000001DB663A5307671A103801C50C0000016700FF20F2
S224FE2AE00C00000367080C0000046600FF1A0838000001DB661470074A2C00046702540082
S224FE2B0011C0C02711FC000BC027103801C54E750838000101DB6600FEEE70064A2C0004CB
S224FE2B206702540011C0C02711FC000AC02770044840538066FC6000FECE11EF00040105B8
S224FE2B40422F0004427801CC427801D46100DB0E46FC270011FC0025C073423801046100EF
S224FE2B60D88841FA02AB6100D8A46100D87C4267307C04002F082F083F2F000E6100FE4E88
S224FE2B806612307C04000C58424F663C0C584F5466364ED06100D852103801C50C00000409
S224FE2BA0673041FA01B96100D8646100D86E41FA01CA6100D858102C00046100D888610049
S224FE2BC0D828205F548F4ED041FA01A16100D83E60DC41FA024F6100D8346100D92061002E
S224FE2BE0D8080C0000516600FF5C41FA02646100D81C60BA264842804281468126804A9387
S224FE2C00661C2681B293661C26CBB7C963EE2648B7D3660E588BB7C963F642804ED22200D3
S224FE2C206002220B201349FA015D4BFA0006600000842A0B4BFA00066000008649FA0163F2
S224FE2C404BFA00066000006E2A004BFA00066000007049FA01524BFA0006600000582A014F
S224FE2C604BFA00066000005A49FA01F44BFA00066000004249FA01964BFA0006600000366C
S224FE2C8070014ED23E3CFFFF08380002C07356CFFFF8671411C6C0717E0E51CFFFFE08382B
S224FE2CA00002C07366024ED608780003C06551CFFFFE60F41C1C67064DFAFFFA60C64ED509
S224FE2CC07807E99D7C0FCC050C060009630406060007060600304DFA000460A851CCFFE46C
S224FE2CE04ED50514051C05248002052C0534056405240524800B053C8006054C0554800E1A
S224FE2D000544055C800F053C0000070D0A455843455054494F4E3A202000070D0A204E4F14
S224FE2D20204D656D6F72792061743A20000D0A4C6F616420446F6E6500070D0A4261642026
S224FE2D404C6F616420436861726163746572000742616420436865636B73756D0007447225
S224FE2D60697665204572726F722000074E6F7420424F4F54204469736B00206F6E20647298
S224FE2D80697665200007424144204D656D6F7279206174200052414D2053697A65203D2038
S224FE2DA000206973200020696E7374656164206F6620000D0A5341474520537461727475FD
S224FE2DC0702054657374205B322E325D0D0A0A436F707972696768742031393833202053F4
S224FE2DE061676520436F6D707574657220546563686E6F6C6F67790D0A416C6C2052696786
S224FE2E006874732052657365727665640D0A00426F6F74696E672066726F6D20466C6F7092
S224FE2E2070790050757420696E20424F4F54206469736B20616E6420707265737320612016
S224FE2E406B6579202851202D207175697473290007426F6F742041626F72746564002028FD
S224FE2E60546573742041626F727465642900202046696C6C696E67206D656D6F72792E2E8B
S224FE2E802E0020204C6F6164696E672E2E2E00202057726974696E672E2E2E0020204D6FCF
S224FE2EA076696E67206D656D6F72792E2E2E000750524F4D2031204261640D0A000750529B
S224FE2EC04F4D2032204261640D0A00427970617373656420496E69740D0A004C6F6F7065BE
S224FE2EE0642054657374730D0A0052414D207772697465206C6F6F700D0A00426F6F746908
S224FE2F006E672066726F6D204861726420447269766500436F756C64206E6F742066696E87
S224FE2F2064200057616974696E6720666F72204472697665205265616479203C512D7175E1
S224FE2F406974733E000D0A4E6F204D6174636820666F756E64002020536561726368696E56
S224FE2F60672E2E2E000D0A4D617463682061742000202D20436F6E74696E75652073656139
S224FE2F80726368202843203D20596573293F2000001F0027002B003300470052005C006A2D
S224FE2FA0007A008F204572726F722061742000556E6B6E6F776E00427573004164647265CC
S224FE2FC0737300496C6C6567616C20496E737472756374696F6E0041726974686D657469E5
S224FE2FE0630050726976696C656765005265736572766564205452415000556E61737369BA
S224FE3000676E6564205452415000556E61737369676E656420496E74657272757074005268
S224FE3020414D205061726974790046756E6374696F6E3A200020204163636573733A2000DA
S224FE30402020496E73743A20000303D1070207000108024A00006100000C423801C250F807
S224FE306001BB4E7548E71C0011FC0000C50708F80000C5037080740011C0C5C1723251C969
S224FE3080FFFE7A0411FC00B0C60711FC0000C60511FC0000C605323C174051C9FFFE11FC8F
S224FE30A00080C60776001638C605E15B1638C605E15B444386FC000C31C301F2967801F0A5
S224FE30C067226E1244430C4300026F185202671C530066A460160C4300026F085202670C4C
S224FE30E0520060EE51CDFF9E50F801BB11C001EF11FC0001C507303C174051C8FFFE4CDFCF
S224FE310000384E75223801D67000103801B934004841B2406200006E484182C048413038D3
S224FE312001B0C4C0C0C142414841944048C231C001E8203801DAB4806D0C944031C201EC7E
S224FE314031C001EA600831C201EA427801ECD27801BC6530B27801BE622A43F8020030190C
S224FE31606708B2406504524160F431C101E27000103801B882C031C101E4484131C101E6DA
S224FE318042004E7511FCFFF501C34E7511FCFFF201C34E752F02343C07D008380001C5811B
S224FE31A067305342672611FC000CC58772016100011C4A3801C36600009270144840083873
S224FE31C00000C58167D45380670260F270FD6000007611FC000DC587720A610000F04A38E5
S224FE31E001C3660000667014484008380000C5816706538067D660F208380001C58167CC21
S224FE3200343C07D008380001C5816728534267BC11FC000CC5877201610000B24A3801C365
S224FE322066287014484008380000C58167D65380679A60F2303C251C51C8FFFE4200427849
S224FE324001C050F801C211C001C3241F4E7508380000C58166604A3801C266066100FF3671
S224FE326066521038C585020000F8807801E611C0C585323801C0927801E467326E0A44415D
S224FE328011FC000DC587600611FC000CC5876100003C4A3801C3661C72FFE01908380000EB
S224FE32A0C58157C9FFF6660E31F801E401C0700011C001C34E7570FD60F61038C583020050
S224FE32C000F0803801BA11C0C5834E7548E7E000E349534111FC0036C60711FC00B0C60743
S224FE32E0303801B211C0C601E04811C0C601741851CAFFFE11C1C605E05911C1C6057418B5
S224FE330051CAFFFE08B80000C503343C08EC51CAFFFE720C484111FC0080C6071038C6051A
S224FE3320E1581038C605E158670C6B0A538166E611FCFFFD01C308F80000C5034CDF000736
S224FE33404E7543F8C7C1247801DE08F80007C50311FC000FC50711FC000DC50711FC000CB3
S224FE3360C5074A114A1111FC0003C78311FC0041C7851011E148101131C001C4343801E85E
S224FE3380670853424A1151CAFFFC343801EA534214D151CAFFFC343801EC670853424A1116
S224FE33A051CAFFFC4A114A1108380000C7836610303801C4B07801E2660E423801C34E7591
S224FE33C011FCFFF801C34E757400143801B880C231C001C011FCFFF401C34E7511FC00025C
S224FE33E0C50711FC0008C50708F80006C50308B80007C50311FC000DC50711FC000CC507F5
S224FE340011FC000EC50711FC0030C60711FC0070C607303801B411C0C601E04811C0C601F9
S224FE3420303801B611C0C603E04811C0C60311FC000BC50711FC000AC50708F80001C5037E
S224FE344070FF08380004C58156C8FFF8660611FCFFFA01C308B80001C50311FC0008C507BB
S224FE346008F80006C50311FC0005C50708F80007C50311FC000FC5074E75225F21DF01DAC7
S224FE348021DF01DE21DF01D62F096100FE2E4A3801BB66046100FBC011FC000A01EE42386A
S224FE34A001C308380005C581660000564A3801BB66046100FBA24AB801DA670000AA610009
S224FE34C0FC44660000426100FD864A3801C3660000366100FF084A3801C36600002A61009C
S224FE34E0FE62660000227000303801EAD1B801DE91B801DA80F801B048C0D1B801D6609809
S224FE350011FCFFFC01C3533801EE6F00005A103801C30C00FFF967260C00FFF867200C0066
S224FE3520FFF7671A0C00FFFA67100C00FFF4660000360C38000301EE6C04423801C2303CAB
S224FE3540FFFF51C8FFFE523801FF103801FF0200001F670A0C38000501EE6600FF426100B0
S224FE3560FB046000FF3A1038C583020000F011C0C583103801C34E75225F261F321F7000BF
S224FE358003C011C001BAE90911C101F42F09423801BB11FC000101B811FC001301B931FCE4
S224FE35A0020001B031FC004001B431FC004801B631FC177001B242780200427801BC4278B3
S224FE35C001BE6100FCF6722F484108380005C581673441FAF94F6100CE346100CE0C6008FD
S224FE35E008380005C581671E6100CF0A670A6100CF0C0C0000516704538166E411FCFFFCE3
S224FE360001C36000FF6270FF08380005C58156C8FFF86700001248410C41002F57C04841F5
S224FE36204A0066AE60BA223C00000000722F484108380000C58167146100CEBA670A6100CB
S224FE3640CEBC0C00005167B4538166E442A741F804002F08203C000004002F006100FE1CE0
S224FE36606600FF047010B6806D2E204343F8060076002211B290660A22290004B2A80004E1
S224FE36806716D2FC00205243B67C00106DE411FC000101C36000FED0873801F4E54B41F877
S224FE36A0040031F0300001BC31F0300201BE11E801F601B911E801F701B831E801F801B0CC
S224FE36C031E801FA01B431E801FC01B631E801FE01B2D0FC004043F80200701F22D851C89B
S224FE36E0FFFC6000FE822C5F11EF0004010508F800010105422F00046100CF6246FC2700E0
S224FE370011FC0025C073423801046100CCDC41FAF7EB6100CCF86100CCD06100FE5C665207
S224FE372042A7307C04002F082F086100FD4E661C307C04000C58424F662E0C584F54662883
S224FE37407000103801F43F002F0E4ED06100CC9A103801C3440041FAF6056100CCB0610094
S224FE3760CCBA6100CC844ED641FAF6016100CC9E60F00C38000101C366D26100CC6C41FA89
S224FE3780F7936100CC8841F801F66100CC8060D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
S224FE37A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
S224FE37C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
S224FE37E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
S224FE3800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
S224FE3820FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
S224FE3840FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
S224FE3860FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
S224FE3880FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
S224FE38A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
S224FE38C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
S224FE38E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
S224FE3900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
S224FE3920FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
S224FE3940FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
S224FE3960FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
S224FE3980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
S224FE39A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
S224FE39C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
S224FE39E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
S224FE3A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
S224FE3A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
S224FE3A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
S224FE3A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
S224FE3A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
S224FE3AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
S224FE3AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
S224FE3AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
S224FE3B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
S224FE3B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
S224FE3B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
S224FE3B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
S224FE3B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
S224FE3BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
S224FE3BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
S224FE3BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
S224FE3C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
S224FE3C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
S224FE3C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
S224FE3C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
S224FE3C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
S224FE3CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
S224FE3CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
S224FE3CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
S224FE3D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
S224FE3D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
S224FE3D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
S224FE3D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
S224FE3D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
S224FE3DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
S224FE3DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
S224FE3DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
S224FE3E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
S224FE3E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
S224FE3E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
S224FE3E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
S224FE3E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
S224FE3EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
S224FE3EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
S224FE3EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
S224FE3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
S224FE3F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
S224FE3F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
S224FE3F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
S224FE3F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
S224FE3FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
S224FE3FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
S224FE3FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
S804FE0000FD

514
SAGE/FILES/v2-3.hex Normal file
View file

@ -0,0 +1,514 @@
S00B000076322D332E68657884
S224FE00000000040000FE0044600004F8600004EC600009646000044E600003F8600003D0DE
S224FE0020600003FE60000404600029A8600029AA6000033A43380203600002FC6000344839
S224FE0040600037104E704FF8040011FC0092C02711FC0038C02511FC0092C06711FC003139
S224FE0060C065700072FF343C42D741F8C0FE3080308151CAFFFA43F8000045F87FFE343C1D
S224FE0080344230113010301251CAFFF8343C06C541F8C00172084A10D0FC001051C9FFF81C
S224FE00A051CAFFEE43FA0006600002C649FA2D0B4BFA000660002C0441FA00362278000861
S224FE00C021C80008B1F80008662E11FC0090C58711FC0090C50711FC0000C58311FC00CD66
S224FE00E0C50311FC0000C58511FC0005C50560044FF8040021C900081038C0216B64E6087B
S224FE010002400006303B00064EFB000200180024001800084238010449FA2DB74BFA085831
S224FE012060002B9849FA2DBB4BFA003860002B8C49FA2DBE4BFA000660002B8074FF720071
S224FE014070001038C023460008000002670272FFE308024000064840204030C151CAFFFCB5
S224FE016060DA41FAFE9C343C1FFF42004201D018D21851CAFFFA4A00671449FA2D394BFAC1
S224FE0180000660002B364A38C0216A0001004A01671449FA2D2F4BFA000660002B1E4A38EC
S224FE01A0C0216A0000E811FC0001C067307C000072014841323CFFFE224145FA00066000B9
S224FE01C02A3A664647FA000C21CB000808F80002C5034FF8040047FA002421CB00087202E9
S224FE01E04841D3C1303CA5A53280B051660E46403280B05166064640D3C160EC4FF80400AC
S224FE020093C145FA0006600029F267084A38C0216A00007A303C00BF41F80100429851C8B9
S224FE0220FFFC548921C901004E6121C9014A21C9014243FA000C21C9000808B80002C50322
S224FE02404FF804006100041C11FC0000C0674A38C0216B1611FC0007C06770FF51C8FFFEF7
S224FE026011FC0006C0676000FEFA6100018241FA2B2B6100019E30380100ED486100021C57
S224FE0280704B610001E06100016660044E7227007228740208380006C0216702725011C216
S224FE02A001C611C101C7423801CA11C201CE11C101CF11FC000101D27206610000FE42381F
S224FE02C001BA2278000841FA003021C8000811FC00AAC58311FC0005C5050C3800AAC58351
S224FE02E0661611FC0000C58350F801BA31FC027001F011FC008001F54FF8040021C90008D7
S224FE03001038C021C07C0030670CB07C00206724B07C0010672621F80100014A21F80100B3
S224FE0320014231FC2700014E41FA004221C801466000064442676100280860DA4A3801BACC
S224FE034067D4203801004840720C92406F12C2FC000A5341303C6F9A51C8FFFE51C9FFF6B7
S224FE0360426770012F006100356660AA4E4F60FC41F8C0734200108011FC0076C007E018B2
S224FE038010801238C021E0181080706E080100036702707E10BC00400241000711FB101450
S224FE03A0C003108011FC0000C003E01810BC00254ED1028040201008040241F8C033424061
S224FE03C0108011FC00B6C007E018108011FB10E4C005E018108011C0C005E01810BC004091
S224FE03E0E01810BC004EE01810BC00274E752F00700D6170700A616C4200616861666164DF
S224FE040061626160201F4E752F0070206156201F4E753F0010186704614A60F8301F4E75F4
S224FE0420E9186126E91861224E752F017203E958611851C9FFFA221F4E752F017207E9984A
S224FE0440610851C9FFFA221F4E753F000200000FB03C0009630406000007060000306104C5
S224FE0460301F4E754A380104662C3F01323CFFFF08380002C07356C9FFF8670811C0C071A6
S224FE0480321F4E7548E7C0C043FA00066000FEE24CDF030360D64E4A4E7548E7F0007200C0
S224FE04A032007400343C2710420382C266044A0367061001619450C34241484184FC000A90
S224FE04C066E84CDF000F4E754A38010466282F011238C0730801000167F61038C071020129
S224FE04E000386604221F4E7511FC0035C07370076100FF7260DA4E494E7508380001C0738D
S224FE05004E7561C4088000070C0000616D0A0C00007A6E04088000054E7521C001067002DB
S224FE0520604E21C001067004604621C001067006603E21C001067008603621C00106700AB4
S224FE0540602E21C00106700C602621C00106700E601E21C001067010601621C001067012F4
S224FE0560600E21C001067014600621C00106701648F87FFE010A4E6821C8014A2A00701668
S224FE0580BA806270BA3C00046206381F261F341F31DF014E21DF014621CF01424FF80400D7
S224FE05A00C0500146700199A6E0018B80C050012661E11FC0001C06711FC0000C0674A3829
S224FE05C001BA670C08F80002C50308B80002C50370FFE01851C8FFFC46FC270011FC00386D
S224FE05E0C02508B8000601504238010443FA000A6000FD7E428560A849FA27164BFA0006C1
S224FE0600600026B849FA2990D8F450004BFA000460EE49FA29964BFA000460E420380146BC
S224FE0620610017F66100FDC80C0500046200034841FA29FE6100FDDC30046100FDEE41FA0A
S224FE064029FB6100FDCE20036100FDF041FA29F86100FDC030026100FDD26100FD926000AA
S224FE0660031641F8000843FA268045FAF9944280301967186B06D08A20C060F24241120052
S224FE06803019D08A20C051C9FFFC60E24E75225F02800000000FD080D089C1893251D3C09F
S224FE06A04ED148E780B02478000847FA001421CB0008101121CA00084CDF0D01B0004E750C
S224FE06C0508F321F46C141FA26586100FD46588F20096100174421CA00084CDF0D0100008B
S224FE06E000014E7508380001C0734E752F00703A6100FD72201F6100FD104E752F00702C18
S224FE07006100FD62201F4E752F0070076100FD56201F4E75C03C007F0C0000206D060C0092
S224FE0720007E6D02702E4E752F092F01224842816100FDD00C00001B6700006E0C0000128B
S224FE0740670000680C00000D674A0C000008661AB3C867DC6100FD0E6100FCAE6100FD06D0
S224FE076051C9FFF25389528260C40C00007F6614B3C867BC61585389528210116100FCE627
S224FE0780544160AC611A428153826B0812C06100FCD4609C610A421912C0221F225F4E7513
S224FE07A08281673C4281602C224842812F0870236100FCB26100FC38B3C86700000C101890
S224FE07C06100FCA2B3C866F6205F6000FF648281660E72013F00103C005C6100FC88301FF9
S224FE07E04E75428010188000660253884E7561F28000670A0C00002067040C00002C4E75ED
S224FE080061E067080C00002067F653884E7561D2244942411219B011568957C9FFFA660091
S224FE082001481021E1581021D4C04ED248E7180042817801E89C61B667540C00002F660E95
S224FE0840383C33334844383C333461A26740040000306D380C0000096F144A04662E040053
S224FE086000070C00000A6D240C00000F6E1E26014A046708E799E39BD2836002E999B684CB
S224FE0880640AD280848267C2B48164BE72FFC1414CDF00184E752F036100FF66428395CA7A
S224FE08A06100FF4C670000480C00002367360C0000246708347801525388602A6100FF307B
S224FE08C06700002C0400003065240C000003641E244093C96100FF18670000180C00002B46
S224FE08E0660C6002528342826100FF42670257832240D5CAD5CAD4FC0154D3D2201FC143F6
S224FE090080804E752F0242826100FEF6670000520C000027671C0C00002E674624016100EB
S224FE0920FF0C6B06241F92814E75241F428153814E756100FEAE6100FEAA670000200C00D9
S224FE094000276712E19A4A0266E0D480828167E6B28264E260D46100FE9666CEC14260C445
S224FE09607001241F22004E756100FA9E703F6100FAF46100FD944FF8040042B801546100F7
S224FE0980FA6E0838000601506700000870546100FAD436380152670C70246100FAC81003F5
S224FE09A06100FAA8703E6100FABC742841F801886100FD7643FA1A686100FE5460B843FA73
S224FE09C01A8C6000FE4A6100FE382838017E387801821010670E6100FEBE668C2809284AD6
S224FE09E031CA01826100FE1A327C01001010670A6100FEA46B00FF726704D3C45389528925
S224FE0A0021C9017E2A09611C6718280B6100FCD667F46100FAEE0C00001367F60C000003A6
S224FE0A2066E44E756100F9C820046100FA0EB8FC0154670C6100F9D2200490946100F9FCB1
S224FE0A406100FCAA760F2644C7496100FC56C7496600FF16101B6100F9C808030000660091
S224FE0A6000066100F9A4BA8B57CBFFDE6100F99A760F2644101B6100FC9C6100F9E8BA8B9D
S224FE0A8057CBFFF24E7543F80154323C20247402601443F80126323C2041600843F8010676
S224FE0AA0323C204474076100FD3A671A903C00306B00FEB678001800B8026E00FEAC6122CD
S224FE0AC06100F92C4E754284611852846100F93A0C04000466046100F9306130B8026DEA77
S224FE0AE04E756100F90A42833001E0880C000020670000066100F96E10016100F968868331
S224FE0B00660610046100F9446100FBE22004E5800280000000FF4A836A4230310000610031
S224FE0B20F90A0C415352663C48E7704036006100F8D870286100F92E428243FA18D214199D
S224FE0B40670E1019E57B650270206100F91860EE4CDF020E70296100F90C600820310000EA
S224FE0B606100F8D84E756100FC7A6600FDFC6100FF226100FF2861186108614861046134B9
S224FE0B804E756100F8846100F8804E756000F86061FA103C00506100F8CC103C0043610052
S224FE0BA0F8C46100FB4820380146307801526000126861D876FF43F8014E223C0000535223
S224FE0BC0600E61C843F8014A223C00005553760142846100FF144E757C0060000C2C7000F7
S224FE0BE072104A10670A6100FC446B00FD7C12006100000E5200B0016DF66100F7F24E752C
S224FE0C006100F7EC41FA00206100F8086100F83C41FA001B3438017C0102670441FA001B39
S224FE0C206100F7F04E755452415020230020204E6F207472616365200020205472616365B1
S224FE0C4020202020000043FA18A26000FBC26100FCB46600FD142A006100FCAA6600FD0AD7
S224FE0C602800D0856100F7882200103C002B614822059284103C002D613E2205C2C4103C84
S224FE0C80002A61344A446746220582C4103C002F61186132103C00726100F7CA103C0065D2
S224FE0CA06100F7C2103C006D48416100F7B86100FA3C30016000F7746100F7AA6100FA2EA7
S224FE0CC020016100F7766100F7406000F73C4E757C106100FB2C2838017E387801821010EE
S224FE0CE067106100FBB26600FC802809284A31CA01826100FB0C327C00141010670C7CFF31
S224FE0D006100FB946B00FC6267062C096B00FC5A52892A092C446100F6D6200E6100F71C67
S224FE0D20B8FC0154670C6100F6E0200E90946100F70A6100F9B848E7060061304CDF0060E6
S224FE0D4021CE017E4A866B065386671E2A0EBA8E650000186100F98E67BC6100F7A60C0071
S224FE0D60001367F60C00000366AC4E75300EE2086500FBF67C07610006F03E00E9586100E4
S224FE0D80F90E0020010001080104014003880428046E0512060606CC053A05A6060606526D
S224FE0DA006CC08070008664E43FA176C3207E049E249610006F659016F5E040100106758EE
S224FE0DC0580166064245611C60063A07610006C4610006FC6100070216076100F9206100B0
S224FE0DE007364E75428543FA171E3207EC5902410003600006B63007020000380C00000852
S224FE0E0067367042610006AE61DA610006C23607EC5B6100072860C030070200003F0C004F
S224FE0E20003C66A64282263A084C080700066704263A0846600000F2203A082A6100067606
S224FE0E407050610006703A07E35D08C500066100064E6100067A08070007670A61126100B3
S224FE0E60F89C61144E7561106100F89261024E753607EC5B600006C6360708C30005600004
S224FE0E800696428560067A4060027AFF203A07D6610006223007EC580200000753006606EE
S224FE0EA0704161000610610005F6610006223607610006646100F8463607EC5B610006642C
S224FE0EC04E7508070008660002043007EF580240000732006100F7B8001000320014001C4E
S224FE0EE0007C011800B201527401600A263A0786428260064282263A0780283A07683007AC
S224FE0F00020000C00C0000C0671843FA16366100059A3A076100057C610005B4610005F69F
S224FE0F204E7520046100058E7A40610005A228034A026614610005DE4A84670A6100F7BE87
S224FE0F402004610005704E7561F66100F7B0610005C44E753207E6590241000708070007AD
S224FE0F606624203A071808070006670C203A07124A016604203A070E6100053A61000550F6
S224FE0F80610005924E754A016756203A06D861000524704D3A07E35D08C50006610005163C
S224FE0FA0610004FC610005287A40610004BC31C001880807000A661E6100000C6100F73E4A
S224FE0FC0610005524E7570236100F49A303801886100F4584E7561E86100F72261E84E75E1
S224FE0FE0203A06AA08070006678E203A069C60880C0700FC6612203A0698610004B8203A00
S224FE10000694610004B04E753A07024500C00C4500C0670A3005E2588A406000FEEE283AAA
S224FE10200678428242836000FED608070007660000983207E6590201000714010C010006B4
S224FE104067520C0100036F14263A065E024200010247000F004700C86000FEA043FA14FC86
S224FE10606100044861000468E20A660E70236100F3F430076100F3D44E753607E75B6100B6
S224FE108004C008070003660A6100F6727A40610004484E75320702410007340143FA14CC3F
S224FE10A0610004080C020002660A610004227A406100042670544A02670870560C0200061B
S224FE10C066046100F3A04E754280600270023207EC59C27C0001D2407A4043FA14AE61006D
S224FE10E003CA610003EA6100042C0807000867186100F60A3607EF5B7020080700066702B5
S224FE11007028B143610004104E753207020100C00C0100C0673E203A058808070008670431
S224FE1120203A05826100038E3A07610003666100039E70236100F32E3007EF580200000730
S224FE11404A00660270086100F3026100F5B0610003C44E7570533807020400380C040008C3
S224FE1160660808870003303C4442611C610003A60C04000866106100F5847A40610003600D
S224FE11803440610003FA4E7543FA1440610003263207EE5902810000001ED3C142803011E4
S224FE11A061000312610003284E757A40320702410F000C410100670A704243FA13EE61CC46
S224FE11C0600C203A04D8610002EC6100030230074A0067106100F24AE158E040548E61087C
S224FE11E0558E4E75610002F83440610003924E750807000866000258203A046A610002B606
S224FE12007051610002B0610002C670236100F25610076100F20C6100F4E43607EC5B6100FE
S224FE1220031C4E753A0743FA13C2612208070008670C61106100F4C6610002DA4E7561F884
S224FE12406100F4BA3607EC5B610002F24E753207E95902410007610002524A45670461000B
S224FE126002326100026A4E75428560023A0743FA139A61DA3607E75B61086100F48036071E
S224FE1280EC5B080700036606610002B24E75610002C04E753007024001F00C40010067C8E2
S224FE12A0EC4872045740670859406600FF787205088700068E7C41006000FE1E3007EC58B7
S224FE12C00240000755406F00FF5C43FA133E7A4053406706E35D594066166100FF72610093
S224FE12E002346100F4183607EC5B610002544E75044710003007024000380C400008660084
S224FE1300FF24203A03A8610001AC3A0761000184610001BC3607E75B61086100F3E03607F6
S224FE1320EC5B610002264E753007024001F878000C400140671078030C4001486708780230
S224FE13400C4001886624203A0368610001686100017E3607EC5B61086100F3A23607E75B5A
S224FE1360E21C650001DC600001D4E8480C0000106700FEF67206E44857406700FF34720700
S224FE1380594067F66000FE9E3007024000C00C4000C067123007024001300C40010067003C
S224FE13A0FECC6000FE803A07E25D43FA12563207E55902410001610000F2610000E26100AB
S224FE13C0010E610001506100F3343607EC5B610001704E7532073A07024500C00C4500C016
S224FE13E06744E6596150610000AA610000E2360702430E00080700056708EC5B6100013E07
S224FE1400601670236100F05E3003EF580200000F660270086100F0346100F2E23607E75B6D
S224FE14206100011A4E75EF59610C4285610000A0610000E24E750241000334070242010021
S224FE1440EC5A824243FA11DC610000604E75702E61000062203A02126100005A6100007076
S224FE146030076100EFC64E752F09224E6100F2346600F4F6301E225F4E752F09224E61003F
S224FE1480F2226600F4E454896100F218201E225F4E75024500C00C05008066027AC03205BC
S224FE14A0EC590201000343FA108AE519024100FF203110002F017203E1984A00670000088F
S224FE14C06100EFA2530651C9FFF0221F4E756100EF3851CEFFFA4E7570236100EF883205AC
S224FE14E0EC59C27C0003B23C000267206100FF7A53016C066100EF2A4E756100EF2E53013D
S224FE15006D086100FF646100EF224E75703F6100EF544E7536071003E60802000007E70B0B
S224FE152086001003024000076100F164001000140018001E00240076008000C672446014AC
S224FE154072416010223A0112600A223A01106004223A010E7403E1991001671C6100EF0675
S224FE15600C00004467060C000041660C3003E618020000076100EED451CAFFDC4E75705B0B
S224FE15806100EEE2D5CE200A558030780152D1C8D1C890A801546100EEA2705D6100EEC6E8
S224FE15A04E756100FEC46100EE8260986100FEBA38006100EE6C70286100EEAA6182610098
S224FE15C0F13C3604EF5B0804000F66066100FF6E60046100FF6C702E6100EE8A7057080488
S224FE15E0000B6702704C6100EE7C70296100EE764E75E61BC63C000710036100F0920012BA
S224FE1600001C0026003E00540010001000104E756100FE566100EE144E756100FE5E610007
S224FE1620EE1A4E756100FE4234406100EDFE223A003C6100FF206100FF464E756100FE2A71
S224FE164038006100EDDC203A00286100FE686000FF6E6100FE844E75284129002841292B1A
S224FE16602D2841294D4F5645574F5244285043292850430043435200535200004E42434402
S224FE168050454100535741504558544C45585457494C4C4547414C005441530042535200E8
S224FE16A0414444515355425155535000434D504D4558470043FA0DB56000F1546100F1D8FB
S224FE16C06600F2A660046100F0402809284A2A0454856100F3506100F01441F80188243C3F
S224FE16E0000000286100F042428110106716223C0000FFFF6100F20E6BCC6E0A134000010C
S224FE1700E080128054890C01002E66BE4E7543F80154323C202474037A01601643F80126C9
S224FE1720323C2041600843F80106323C2044740842856100F0AE671A903C00306B00F22A15
S224FE1740B0056B00F224B0026C00F21E4282610E4E75200561085280B0026DF84E7542832D
S224FE17602F023A0128002C00E5864A82660E6100F0904A10662260046100EF8E320561005E
S224FE1780EC6E6100F3646100EF64742841F801886100EF961010672042816100F1686BD8D5
S224FE17A0660000160286000000FF86836A063380600060042380600032051004241F4E75DF
S224FE17C06100F0206600F1A26100FF526100FF586106611E610E4E7543F80146323C504397
S224FE17E06000001843F8014E323C535276FF6000000C43F8014A323C555376014282428057
S224FE18006100FF5E4E757CFF7A0142806100EFD467144486903C00306B00F14EB03C000190
S224FE18206E00F1463A00360060046100EEDC3643D7CB284BD7CB4A866B0A675A6100EFC2B9
S224FE18404A106614616A6100EEA4742841F801886100EED66100EFAA101067320C00002E83
S224FE1860660607B8015060266100F02C6BBC6100EF90243C0000FFFF6100EFB26BAC426CBA
S224FE188001723940017607F80150274901605243B6456F9A4E75611860F4427265616B7043
S224FE18A06F696E742000496E61637469766500006100EB3C41FAFFE46100EB58100361005A
S224FE18C0EB8A6100EE2807380150660A41FAFFD86100EB404E75202B01606100EB5E610001
S224FE18E0EB2870286100EB7E302C01766100EB3C6100EE0A302C01726100EB307029610077
S224FE1900EB644E75760078104A10671C6100EF1E6B00F056160018006100EEE60C000054F5
S224FE192067460C00004E67386100EAC441FA004C6100EAE010036100F2C86100EDB0742875
S224FE194041F801886100EDE26100EEB667240C00005467140C00004E67066100EDAC60C83E
S224FE19603238017C078160063238017C07C131C1017C5203B6046DBC4E752854297261639B
S224FE198065206F7220284E296F2074726163650043FA0AF86000EE78243C000000FF616C50
S224FE19A06600EFC61A00E1401005600C243C0000FFFF61586600EFB23A00484030056008D0
S224FE19C0428261486600EFA241FA14AA6100EA4461000942E19812C0538466F821CA0008F9
S224FE19E04E7548E7F0006100EEAE661A28096100EEA62449C9896B0E6E0698895284600458
S224FE1A00D5C9538A42804CDF000F4E7561D4660622026100EEF04E7561F266142C009887AA
S224FE1A206D00EF4670FF4A10670A22026100EED66600EF3641FA15266100E9D8610008D61C
S224FE1A404E7543FA0AB46000EDC6243C000000FF7E0161C41219C200B206670453846CF468
S224FE1A606100009660F6243C0000FFFF7E0261A81219E1991211C240B246670453846CF0CF
S224FE1A806100007660F642827E04618C2649548B1219E1991211E199121BE1991213C28045
S224FE1AA0B286670453846CE86100004E60F66100FF326600EEB448E708606100FF26660033
S224FE1AC0EEA82A492C044CDF0610C34D41FA148E6100E9406100083E9C8465182849528982
S224FE1AE02E04264D121CB21B6606538766F6610853866CE861024E7148E7FE7E663E41FA5F
S224FE1B00146B6100E90E538920096100030C6100EBDC7203E198101951C9FFFA6100E91CBE
S224FE1B2041FA14556100E8EC6100E9D80C00004366126100E9304CDF7E7F4E7541FA140D1F
S224FE1B406100E8D04CDF7E7F21CA00086000EE286100E8B66100E8B243FA093A6000ECB062
S224FE1B6043FA093C6000ECA86100ED2C6600EDFA20096100E8C66100EB7410116100E8A221
S224FE1B804E756100ED126600EDE03C09080600006600EDD620096100E8A26100EB5030117F
S224FE1BA06100E8884E7543FA08FD6000EC626100ECE66600EDB4223C000000FF6100ED4673
S224FE1BC06600EDA612804E756100ECCC6600ED9A3C09080600006600ED90223C0000FFFF1C
S224FE1BE06100ED226600ED8232804E756100EC1274076100EC386B00ED7022006000E7BCDC
S224FE1C0043FA08AA6000EC086100006443FA07B654894A516700ED523014C059B05966F0E5
S224FE1C20D8D121CC016808F80002015008F800040150600261387401610001BA426A01724F
S224FE1C4051CAFFF66002612608B80005015008F80006015008F80007015010380150020028
S224FE1C600007660608B800060150600001506100EB901010670C6100EC1E6600ECEC21C924
S224FE1C80014661066100E7684E752C380146284608060000671241FA001C6100E776200645
S224FE1CA0610001766000ECD0224C6100E9F66600ECB84E75496C6C6567616C2070726F6720
S224FE1CC072616D20737461727420616464726573733A20006100E71843FA07DC6000EB3018
S224FE1CE0083800060150670461A0604E4E7508F8000501506040619208B8000301500C1054
S224FE1D000049660808F80003015052887005083800050150660270104A10670E747F6100C5
S224FE1D20EAE06100EB086B00EC406100E6C2600C08B8000501506100FF36700111C0015136
S224FE1D4008F80006015008B80007015030140240FFF00C404E406664301C0240000F3C38E7
S224FE1D60017C41FA002C0106661C21CC016808F80007015008F80002015008B800040150DD
S224FE1D80673A41FA00216100E68A6100E662602C2A2A2A2054726163696E67205452415080
S224FE1DA0202A2A2A002A2A2A204753207465726D696E61746564202A2A2A00002878014678
S224FE1DC03C38014E08380006015066060886000F600408C6000F2078014A4E602E780142E2
S224FE1DE02F0C3F064CF87FFF01064E7308B8000601504E7542803242D3C92449D3C90538E4
S224FE1E000150670E226901606100E8986600000652804E7553804E756100E6203078015233
S224FE1E20D0C8D0C84A780152672E6100E5DC2F0070286100E63070246100E62A30380152A5
S224FE1E406100E6086100E8A6201F90A801546100E5EA70296100E60E4E7554726163653A6B
S224FE1E6020000838000601506700FF52083800070150672608B80006015074006100FF766A
S224FE1E806B00EAE667083551016C32BC4E4F52420C42000366E66000FF2441FAFFBE203813
S224FE1EA0014621C0017E6100E56A28406100FF6AD0FC015431C801826100E832224C6100AF
S224FE1EC0E7E2661430116100E5626100E53C6100E5382C496100EE96083800050150670A72
S224FE1EE041F8018842106100EC7E533801516F1E083800030150671A6100E7EA6714610073
S224FE1F00E6020C00001367F60C00000366046000EA666100E4DA6000FE280D0A556E6578D5
S224FE1F2070656374656420627265616B20706F696E743A2000000D0A427265616B3A20000A
S224FE1F4042854286283801465584760041FAFFCC74026100FEA06F32B3C4661E41FAFFD8D0
S224FE1F6076020C02000267123A2A01723C2A0176BC4567065245354501720C514E4F670650
S224FE1F8005B80150600432AA016C51CAFFC60838000201506728B8B80168662208B800025E
S224FE1FA0015008B800040150661421C4014608F80006015008B8000701506000FEA6203847
S224FE1FC00146908321C00146BC456600FC824A436600FED028440C544E4F6600FEC620041F
S224FE1FE06000FEC043FA04E46000E82411FC000101BB6004423801BB41FA0E8E6100E4149B
S224FE20006076428574016100E8246B00E95C3C00243C0000FFFF6100E8146B00E94C3F00B8
S224FE20206100E8746600E9422F0942826100E7FE6B00E9362F003F064A85670E41FA0E572B
S224FE20406100E3D061000992600C41FA0E3C6100E3C26100097E6700000E41FA000C610071
S224FE2060E3B26100E3BC4E750D0A4469736B206572726F723A20000061740C000051670026
S224FE208000C00C00005366F0420561621E00610000BC1C0153064281610000B2610000AE28
S224FE20A026410C070030660E4A0667066100009E60F6617460C20C0700326614220B6100A9
S224FE20C0008C26414A0667EA6100008216C160F40C07003167EE0C07003966644A06666096
S224FE20E0614641FA0C4F6100E32A6000E88A4A3801BB672408380001C033670A1038C031B9
S224FE2100088000074E756100E3F267E26100E3F40C00005166D84E756100E3AE0C00000D4A
S224FE21206700E2CC6000E33E6122460566024E75588F41FA0C216100E2DA6000E83A508F40
S224FE214041FA0BFD6100E2CC6000E82C61086106DA0153064E7561960C0000306DE00C0063
S224FE216000396E0A04000030E989D2004E750C0000416DCA0C0000466EC45F0060E643FA86
S224FE218003436000E68A7A016000FE7A6000E7E843FA03426000E678202053797374656D9F
S224FE21A0207265696E697469616C697A696E672E2E2E2E0046FC270011FC0025C07342381A
S224FE21C0010441FAFFD46100E24A70FF51C8FFFE6000DE724280428710100C0000526606B2
S224FE21E03E3C010052881010670A74016100E63E6B00E77680473F00610009464E754A3839
S224FE220001BA6700E764428042877C0110100C00005266063E3C010052881010675C0C0018
S224FE222000206714040000306D00E73E0C0000036E00E7368E0052886100E5C64A00673A41
S224FE22400C0000236600001652884A10672C740F6100E5DA6B00E7123C00601E740743F892
S224FE226001F62C09429142A90004422900086100E572670612C051CAFFF63F072F06610017
S224FE2280164E4E754E7574186100E16451CAFFFA4E7543FAE2D621C9002443FAE2C621C976
S224FE22A000BC4E7542801010670A74026100E57E6B00E6B631C00152E540D07C015431C00D
S224FE22C001824E756100E5D06600E69E28096100E5C66B00E694C98966049889600253847D
S224FE22E06500E68626496100E5AE6600E67C41FA0BB26100E11E7201B7C96406D3C4D7C4F8
S224FE230072FF61101293D3C1D7C153846CF621CA00084E752478000849FA000821CC000834
S224FE23204E7541FA09FC6100E0EA548F201F6100FAE821CA00086000E63E43FA01B560003D
S224FE2340E4CE3F3C00016002426774016100E4DE6B00E6163F00243C0000FFFF6100E4CE92
S224FE23606B00E6063F00427801CC427801D411FC000101DB3F172F3C000004002F3C000094
S224FE238010003F2F000C4A6F001067066100064A60046100063E662A702E6100E0C808F889
S224FE23A0000101DB6100E15467CA6100E11C11FC0007C02711FC0009C027423801DB5C8FDF
S224FE23C04E75705860D4F0FF60000004F00060000002F0F850C80004FFB84E900002FFB844
S224FE23E04EA80004FFB84EB00004FFBF4EB80004FFBF4EB90006FFBF4EBA0004FFBF4EBB03
S224FE24000004FFF04E400002000000000000015402530958014E015A0156014300000E4494
S224FE2420A0E55396F24672F52486FE4DA6FE5032F754B6F847E2F75760FD4CC6FB00C2F8DD
S224FE24404972FD4128E8451CFF5824F6094D7AE5521AE74450E64146E65044E75366E7553F
S224FE246076E7243AE6428CE75492E7094D51F25255F344BBF241B1F2506DF35379F35587E3
S224FE2480F324A3F2429BF35499F402420EF55722F54C36F50249CCF64F12F75358F7014266
S224FE24A0CAF657E4F6014209F75723F7024F88F7439AF7535CF703427AF84536F95238F87D
S224FE24C04E40F80141C9FC46C3FC024122FB542AFB4638FB064600FD482AFD47B0FD53E036
S224FE24E0FC568EE143B2FD54BEFD0144E6E75264E7015257FE5751FE034252F5576EF54C88
S224FE25008EF54DB6F5005453540043484700434C5200534554004F524900414E44495355F5
S224FE252042494144444942000000454F5249434D50492E4200002E5700002E3F00002E4C85
S224FE254000004E454758434C52004E4547004E4F54000000000054535400545241505452C2
S224FE256041504C494E4B554E4C4B524553454E4F500053544F505254450034453734525488
S224FE2580530054524150525452004A5352004A4D500043484B004C45410044495655444973
S224FE25A056534D554C554D554C535241460048494C53434343534E45455156435653504CBF
S224FE25C04D4947454C5447544C455400460048494C53434343534E45455156435653504C1D
S224FE25E04D4947454C5447544C454F52000053554200454F5200434D5000414E4400414441
S224FE260044005355424141444441534243445355425800000000434D504141424344414430
S224FE26204458415352004C535200524F5852524F520041534C004C534C00524F584C524F35
S224FE26404C0048E760401219143C00AD1038C0510800000756CAFFF6671A080000066614AE
S224FE266011D9C053740951CAFFFE530166DA4CDF02064E7511FC000101C560F248E7604046
S224FE268043FA09D461BC6624720243F801C36174661A123801C3020100C0670C080100065B
S224FE26A0670472036002720211C101C54CDF02064E7548E76040720743F801BC421161449B
S224FE26C0663C123801BC020100C0672E0801000667267205103801BDE208651E7206E4080C
S224FE26E065187207E40865127208E208650C7209E4086506720A6002720211C101C54CDFC2
S224FE270002064E75343C10FE1038C0510800000756CAFFF6671608000006671012F8C053D1
S224FE2720740951CAFFFE530166DA4E7511FC000101C54E752F017002484008380000C06386
S224FE27406612538066F411FC0002C02711FC000401C5600C4A02662012F8C053534166D6D9
S224FE276011FC0001C02711FC0000C0276100FF44221F4A3801C54E7511D9C053534166B6D0
S224FE278060DE48E76040720143FA08C96100FEB466387402484208380000C063660C53824D
S224FE27A066F411FC000401C56020422C00036100FECC67160C38000301C5660E0C2C005043
S224FE27C00001660651C9FFC270034CDF02064E7548E760407202103801D6B02C0003674C51
S224FE27E043F801B032BC030F42290002137801D600036100FE4E6634740248420838000091
S224FE2800C063660C538266F411FC000401C5601C6100FE6A660A197801D600034200600C4C
S224FE28206100FF60660651C9FFAE70034CDF02064E750000000000000000423801C54A2C83
S224FE284000006700010C3F077E0111FC000FC02711FC0000C02711FC0003C02743FA07F119
S224FE286011FC000EC0276100FDDA663870064A2C00046702540011C0C02711FC000AC0271A
S224FE288070FF51C8FFFE08380000C06367086100FDEC423801C56100FEEA671C0C38000341
S224FE28A001C5670451CFFFA43E1F70014E7570080838000001DB667070044840538066FCF5
S224FE28C0197CFFFF000243FA07906100FD7666D4343CFFFE1038C0510800000756CAFFF694
S224FE28E0660E11FC0002C02711FC000401C560B86100FDC066AE103801C1B02C00026708F3
S224FE29006DC41940000260BE0C000008671A0C00000967100C000010673E0C00000A662686
S224FE29207418600674206002742A0C38000201C26614397C02000006194000021942000513
S224FE29403E1F42004E7511FC000901C56000FF5A11FC000B01C54E750C38000101C266E688
S224FE2960397C01000006742060CE4A2C0000675A4281323C020082EC00064282343801DEE9
S224FE2980C4C14281122C000284C14241082C000000006604E24AE31111C101D711C201D6D2
S224FE29A0B42C00016C244842122C00029202C2EC0006B2B801E06F04223801E0520211C271
S224FE29C001D831C101DC42004E7511FC000B01C54E75423801DA600611FC000101DA225F81
S224FE29E049F801C6301F670449F801CE21DF01E021DF01E431DF01DE2F097E034A6C0006D8
S224FE2A00660001146100FE34660000EA4AB801E0670000E211FC0003C0274A3801DA672C42
S224FE2A2008380001C063670A11FC000C01C5600000C4102C0001E208B03801D66F0811FC51
S224FE2A40000DC027600611FC000CC0276100FF1C660000A26100FD7A667443F801B0303C8B
S224FE2A6009454A3801DA6602524032C0103801D7E50812C012F801D612F801D712F801D837
S224FE2A80302C0006E04812C012EC000212EC000512FC00FF43F801B06100FBA866302278A7
S224FE2AA001E44281323801DC143801DA6100FC86661C303C032051C8FFFED3B801E493B838
S224FE2AC001E082FC0200D37801DE6000FF400838000001DB663A5307671A103801C50C0018
S224FE2AE000016700FF200C00000367080C0000046600FF1A0838000001DB661470074A2CBC
S224FE2B0000046702540011C0C02711FC000BC027103801C54E750838000101DB6600FEEEFA
S224FE2B2070064A2C00046702540011C0C02711FC000AC02770044840538066FC6000FECED2
S224FE2B4011EF00040105422F0004427801CC427801D46100DB0E46FC270011FC0025C073C5
S224FE2B60423801046100D88841FA02AB6100D8A46100D87C4267307C04002F082F083F2F63
S224FE2B80000E6100FE4E6612307C04000C58424F663C0C584F5466364ED06100D852103824
S224FE2BA001C50C000004673041FA01B96100D8646100D86E41FA01CA6100D858102C000495
S224FE2BC06100D8886100D828205F548F4ED041FA01A16100D83E60DC41FA024F6100D834C7
S224FE2BE06100D9206100D8080C0000516600FF5C41FA02646100D81C60BA26484280428116
S224FE2C00468126804A93661C2681B293661C26CBB7C963EE2648B7D3660E588BB7C963F68D
S224FE2C2042804ED222006002220B201349FA015D4BFA0006600000842A0B4BFA000660001B
S224FE2C40008649FA01634BFA00066000006E2A004BFA00066000007049FA01524BFA000605
S224FE2C60600000582A014BFA00066000005A49FA01F44BFA00066000004249FA01964BFA25
S224FE2C8000066000003670014ED23E3CFFFF08380002C07356CFFFF8671411C6C0717E0EEC
S224FE2CA051CFFFFE08380002C07366024ED608780003C06551CFFFFE60F41C1C67064DFAEE
S224FE2CC0FFFA60C64ED57807E99D7C0FCC050C060009630406060007060600304DFA000432
S224FE2CE060A851CCFFE44ED5051A0522052A80020532053A056A052A052A800B0542800614
S224FE2D000552055A800E054A0562800F05420000070D0A455843455054494F4E3A20200099
S224FE2D20070D0A204E4F204D656D6F72792061743A20000D0A4C6F616420446F6E65000789
S224FE2D400D0A426164204C6F616420436861726163746572000742616420436865636B7386
S224FE2D60756D00074472697665204572726F722000074E6F7420424F4F54204469736B00EC
S224FE2D80206F6E206472697665200007424144204D656D6F7279206174200052414D20530A
S224FE2DA0697A65203D2000206973200020696E7374656164206F6620000D0A5341474520BB
S224FE2DC0537461727475702054657374205B322E335D0D0A0A436F707972696768742031A7
S224FE2DE039383320205361676520436F6D707574657220546563686E6F6C6F67790D0A4169
S224FE2E006C6C205269676874732052657365727665640D0A00426F6F74696E672066726F96
S224FE2E206D20466C6F7070790050757420696E20424F4F54206469736B20616E64207072E4
S224FE2E406573732061206B6579202851202D207175697473290007426F6F742041626F7296
S224FE2E60746564002028546573742041626F727465642900202046696C6C696E67206D6529
S224FE2E806D6F72792E2E2E0020204C6F6164696E672E2E2E00202057726974696E672E2ED6
S224FE2EA02E0020204D6F76696E67206D656D6F72792E2E2E000750524F4D20312042616431
S224FE2EC00D0A000750524F4D2032204261640D0A00427970617373656420496E69740D0AFD
S224FE2EE0004C6F6F7065642054657374730D0A0052414D207772697465206C6F6F700D0A06
S224FE2F0000426F6F74696E672066726F6D204861726420447269766500436F756C64206ECA
S224FE2F206F742066696E64200057616974696E6720666F7220447269766520526561647961
S224FE2F40203C512D71756974733E000D0A4E6F204D6174636820666F756E6400202053650B
S224FE2F6061726368696E672E2E2E000D0A4D617463682061742000202D20436F6E74696EF7
S224FE2F80756520736561726368202843203D20596573293F2000001F0027002B0033004712
S224FE2FA00052005C006A007A008F204572726F722061742000556E6B6E6F776E0042757394
S224FE2FC0004164647265737300496C6C6567616C20496E737472756374696F6E0041726990
S224FE2FE074686D657469630050726976696C656765005265736572766564205452415000A2
S224FE3000556E61737369676E6564205452415000556E61737369676E656420496E74657212
S224FE3020727570740052414D205061726974790046756E6374696F6E3A2000202041636362
S224FE30406573733A20002020496E73743A20000303D1070207000108024A00006100000CE7
S224FE3060423801C250F801BB4E7548E71C0011FC0000C50708F80000C5037080740011C028
S224FE3080C5C1723251C9FFFE7A046100004A967801F067226E1244430C4300026F18520208
S224FE30A0671C530066D860160C4300026F085202670C520060EE51CDFFD250F801BB11C090
S224FE30C001EF11FC0001C507303C174051C8FFFE4CDF00384E7511FC00B0C60711FC00008D
S224FE30E0C60511FC0000C605323C174051C9FFFE11FC0080C60776001638C605E15B1638DB
S224FE3100C605E15B444386FC000C31C301F24E75223801D67000103801B934004841B24094
S224FE31206200006E484182C04841303801B0C4C0C0C142414841944048C231C001E820382E
S224FE314001DAB4806D0C944031C201EC31C001EA600831C201EA427801ECD27801BC6530CB
S224FE3160B27801BE622A43F8020030196708B2406504524160F431C101E27000103801B85A
S224FE318082C031C101E4484131C101E642004E7511FCFFF501C34E7511FCFFF201C34E759F
S224FE31A02F02343C07D008380001C58167305342672611FC000CC58772016100011C4A387C
S224FE31C001C3660000927014484008380000C58167D45380670260F270FD6000007611FC85
S224FE31E0000DC587720A610000F04A3801C3660000667014484008380000C58167065380C2
S224FE320067D660F208380001C58167CC343C07D008380001C5816728534267BC11FC000C34
S224FE3220C5877201610000B24A3801C366287014484008380000C58167D65380679A60F2F0
S224FE3240303C251C51C8FFFE4200427801C050F801C211C001C3241F4E7508380000C581BF
S224FE326066604A3801C266066100FF3666521038C585020000F8807801E611C0C585323896
S224FE328001C0927801E467326E0A444111FC000DC587600611FC000CC5876100003C4A3895
S224FE32A001C3661C72FFE01908380000C58157C9FFF6660E31F801E401C0700011C001C378
S224FE32C04E7570FD60F61038C583020000F0803801BA11C0C5834E7548E7E000E3495341C5
S224FE32E011FC0036C60711FC00B0C607303801B211C0C601E04811C0C601741851CAFFFE1A
S224FE330011C1C605E05911C1C605741851CAFFFE08B80000C503343C08EC51CAFFFE720C11
S224FE3320484111FC0080C6071038C605E1581038C605E158670C6B0A538166E611FCFFFDFE
S224FE334001C308F80000C5034CDF00074E7543F8C7C1247801DE08F80007C50311FC000FC0
S224FE3360C50711FC000DC50711FC000CC5074A114A1111FC0003C78311FC0041C7851011E8
S224FE3380E148101131C001C4343801E8670853424A1151CAFFFC343801EA534214D151CA74
S224FE33A0FFFC343801EC670853424A1151CAFFFC4A114A1108380000C7836610303801C45E
S224FE33C0B07801E2660E423801C34E7511FCFFF801C34E757400143801B880C231C001C072
S224FE33E011FCFFF401C34E7511FC0002C50711FC0008C50708F80006C50308B80007C5032A
S224FE340011FC000DC50711FC000CC50711FC000EC50711FC0030C60711FC0070C60730383B
S224FE342001B411C0C601E04811C0C601303801B611C0C603E04811C0C60311FC000BC5071D
S224FE344011FC000AC50708F80001C50370FF08380004C58156C8FFF8660611FCFFFA01C379
S224FE346008B80001C50311FC0008C50708F80006C50311FC0005C50708F80007C50311FC57
S224FE3480000FC5074E75225F21DF01DA21DF01DE21DF01D62F096100FE2E4A3801BB66040C
S224FE34A06100FBBA5D8F0C38008001F56700010811FC000A01EE423801C308380005C5810E
S224FE34C0660000684A3801BB66046100FB904AB801DA6700026A6100FC3866000054610027
S224FE34E0FD7A4A3801C3660000486100FEFC4A3801C36600003C6100FE56660000344A384A
S224FE350001F5670C6A0000E8423801F5610001FA7000303801EAD1B801DE91B801DA80F85A
S224FE352001B048C0D1B801D6608611FCFFFC01C3533801EE6F00005A103801C30C00FFF96A
S224FE354067260C00FFF867200C00FFF7671A0C00FFFA67100C00FFF4660001E40C380003C1
S224FE356001EE6C04423801C2303CFFFF51C8FFFE523801FF103801FF0200001F670A0C3884
S224FE3580000501EE6600FF306100FAE06000FF284A3801F567186A00011C423801F5102FB0
S224FE35A0000011C001EF11C0C5C1600001920C00FFF86600018A11FC000101F51F7801EF7E
S224FE35C0000011FC000A01EF11F801EFC5C1422F00021F7C000100011F7C00020003423838
S224FE35E001EE303C257F51C8FFFE6000FECA102F00010C0000016700007A0C0000036700E7
S224FE36000086102F00026604502F000352001F4000020C0000056D00009C0C2F00020001E9
S224FE3620671E103801EF1F400005902F00046500006AE208D02F000411C001EF6000006264
S224FE36401F7801EF000411FC00F501EF1F7C00030001303C257F51C8FFFE1F7C0002000385
S224FE3660422F000211F801EFC5C1423801EE6000FE460438000F01EF6404423801EF1F7CA0
S224FE36800002000160D40638000F01EF640450F801EF1F7C0004000160C011EF000001EF63
S224FE36A011F801EFC5C150F801F511FC000A01EE6000FDFE532F0003670E423801EE11F87D
S224FE36C001EFC5C16000FDF0422F00021F7C00020003102F00010C0000026D2267180C00A9
S224FE36E000036708533801EF67B060CE0438000A01EF65A660C4523801EF659E60BC063859
S224FE3700000A01EF659460B248E75000303C258051C8FFFE11FC0000C507705051C8FFFE4C
S224FE37206100F9B431F801F201F011FC0001C507303C257F51C8FFFE4CDF000A4E7510382B
S224FE3740C583020000F011C0C5835C8F103801C34E75225F261F321F700003C011C001BA83
S224FE3760E90911C101F42F09423801BB11FC000101B811FC001301B931FC020001B031FC71
S224FE3780004001B431FC004801B631FC177001B242780200427801BC427801BE6100FB286E
S224FE37A0722F484108380005C581673441FAF77B6100CC606100CC38600808380005C58124
S224FE37C0671E6100CD36670A6100CD380C0000516704538166E411FCFFFC01C3600000DE36
S224FE37E070FF08380005C58156C8FFF86700001248410C41002F57C048414A0066AE60BA21
S224FE3800223C00000000722F484108380000C58167146100CCE6670A6100CCE80C00005126
S224FE382067B4538166E442A741F804002F08203C000004002F006100FC4E6600008070104F
S224FE3840B6806D2E204343F8060076002211B290660A22290004B2A800046716D2FC00207D
S224FE38605243B67C00106DE411FC000101C36000004C873801F4E54B41F8040031F030002D
S224FE388001BC31F0300201BE11E801F601B911E801F701B831E801F801B031E801FA01B476
S224FE38A031E801FC01B631E801FE01B2D0FC004043F80200701F22D851C8FFFC1038C583F7
S224FE38C0020000F011C0C583103801C34E752C5F11EF0004010508F800010105422F0004FA
S224FE38E06100CD8046FC270011FC0025C073423801046100CAFA41FAF6096100CB166100C8
S224FE3900CAEE6100FE4E665242A7307C04002F082F086100FB72661C307C04000C58424F8B
S224FE3920662E0C584F5466287000103801F43F002F0E4ED06100CAB8103801C3440041FAA6
S224FE3940F4236100CACE6100CAD86100CAA24ED641FAF41F6100CABC60F00C38000101C3D2
S224FE396066D26100CA8A41FAF5B16100CAA641F801F66100CA9E60D2FFFFFFFFFFFFFFFF82
S224FE3980FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
S224FE39A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
S224FE39C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
S224FE39E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
S224FE3A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
S224FE3A20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
S224FE3A40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
S224FE3A60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
S224FE3A80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
S224FE3AA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
S224FE3AC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
S224FE3AE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
S224FE3B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
S224FE3B20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
S224FE3B40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
S224FE3B60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
S224FE3B80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
S224FE3BA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
S224FE3BC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
S224FE3BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
S224FE3C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
S224FE3C20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
S224FE3C40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
S224FE3C60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
S224FE3C80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
S224FE3CA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
S224FE3CC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
S224FE3CE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
S224FE3D00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
S224FE3D20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
S224FE3D40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
S224FE3D60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
S224FE3D80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
S224FE3DA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
S224FE3DC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
S224FE3DE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
S224FE3E00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
S224FE3E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
S224FE3E40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
S224FE3E60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
S224FE3E80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
S224FE3EA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
S224FE3EC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
S224FE3EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
S224FE3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
S224FE3F20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
S224FE3F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
S224FE3F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
S224FE3F80FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
S224FE3FA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
S224FE3FC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
S224FE3FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
S804FE0000FD

435
SAGE/chip_defs.h Normal file
View file

@ -0,0 +1,435 @@
/* chip_defs.h: definitions for several chips
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
22-Jan-10 HV Initial version
*/
#ifndef CHIP_DEFS_H_
#define CHIP_DEFS_H_
#include "sim_imd.h"
#include "sim_sock.h"
#include "sim_tmxr.h"
/*****************************************************************************************
* General implementation note:
*
* Each chip device is implemented through a specific data structure, e.g. struct i8251
* The address of this data structure MUST be passed to the device->ctxt variable.
* The data structure MUST contain a PNP_INFO attribute at the beginning.
*
* In case each unit of a complex device has an own chip, device->ctxt points to an array
* of as much elements as there are units.
* The device reset routine MUST call add_iohandler and del_iohandler depending on
* enable or disable of the device. add_iohandler and del_iohandler will be passed
* the corresponding address of the data structure for the chip (device->ctxt).
*
*****************************************************************************************/
/* set this to 0 to remove debug messages */
#ifndef DBG_MSG
#define DBG_MSG 1
#endif
/* generic debug tracing support */
#if DBG_MSG==1
extern FILE* sim_deb;
#define ADDRESS_FORMAT "[0x%08x]"
#if UNIX_PLATFORM
#define NLP "\r\n"
#else
#define NLP "\n"
#endif
#define TRACE_PRINT(level,args)\
if(sim_deb && chip->dev->dctrl & level) { \
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
fprintf args; fputs(NLP,sim_deb); }
#define TRACE_PRINT0(level,fmt)\
if(sim_deb && chip->dev->dctrl & level) { \
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
fprintf(sim_deb,fmt NLP); }
#define TRACE_PRINT1(level,fmt,arg1)\
if(sim_deb && chip->dev->dctrl & level) { \
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
fprintf(sim_deb,fmt NLP,arg1); }
#define TRACE_PRINT2(level,fmt,arg1,arg2)\
if(sim_deb && chip->dev->dctrl & level) { \
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
fprintf(sim_deb,fmt NLP,arg1,arg2); }
#else
#define TRACE_PRINT(level,args)
#define TRACE_PRINT0(level,fmt)
#define TRACE_PRINT1(level,fmt,arg1)
#define TRACE_PRINT2(level,fmt,arg1,arg2)
#endif
/*****************************************************************************************
* general terminal multiplexer/socket support
*****************************************************************************************/
typedef struct {
int pfirst;
int prate;
TMLN ldsc;
TMXR desc;
UNIT* term;
UNIT* poll;
} SERMUX;
t_stat mux_attach(UNIT*,char*,SERMUX*);
t_stat mux_detach(UNIT*,SERMUX*);
/*****************************************************************************************
* 8259 PIC
*****************************************************************************************/
#define I8259_ICW1 0x10
#define I8259_ICW1_A765 0xe0
#define I8259_ICW1_LTIM 0x08
#define I8259_ICW1_ADI 0x04
#define I8259_ICW1_SNGL 0x02
#define I8259_ICW1_IC4 0x01
#define I8259_ICW4_SFNM 0x10
#define I8259_ICW4_BUF 0x08
#define I8259_ICW4_MS 0x04
#define I8259_ICW4_AEOI 0x02
#define I8259_ICW4_UPM 0x01
#define I8259_OCW2_MODE 0xe0
#define I8259_OCW2_LEVEL 0x07
#define I8259_OCW3_ESMM 0x40
#define I8259_OCW3_SMM 0x20
#define I8259_OCW3 0x08
#define I8259_OCW3_POLL 0x04
#define I8259_OCW3_RR 0x02
#define I8259_OCW3_RIS 0x01
typedef struct i8259 {
PNP_INFO pnp;
DEVICE* dev; /* backlink to device */
t_stat (*write)(struct i8259* chip,int port,uint32 value);
t_stat (*read)(struct i8259* chip,int port,uint32* value);
t_stat (*reset)(struct i8259* chip);
int state;
int rmode;
int32 imr;
int32 isr;
int32 irr;
int32 icw1;
int32 icw2;
int32 icw4;
int32 prio; /* which IR* has prio 7? */
t_bool autoint;
int intlevel;
int intvector;
} I8259;
extern t_stat i8259_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
extern t_stat i8259_read(I8259* pic,int addr,uint32* value);
extern t_stat i8259_write(I8259* pic,int addr, uint32 value);
extern t_stat i8259_reset(I8259* chip);
extern t_stat i8259_raiseint(I8259* chip,int level);
/* Debug flags */
#define DBG_PIC_RD (1 << 0)
#define DBG_PIC_WR (1 << 1)
#define DBG_PIC_II (1 << 2)
#define DBG_PIC_IO (1 << 3)
extern DEBTAB i8259_dt[];
/*****************************************************************************************
* 8251 USART
*****************************************************************************************/
#define I8251_AMODE_STOP 0xc0
#define I8251_AMODE_S1 0x40
#define I8251_AMODE_S15 0x80
#define I8251_AMODE_S2 0xc0
#define I8251_MODE_EP 0x20
#define I8251_MODE_PEN 0x10
#define I8251_AMODE_BITS 0x0c
#define I8251_AMODE_BITS5 0x00
#define I8251_AMODE_BITS6 0x04
#define I8251_AMODE_BITS7 0x08
#define I8251_AMODE_BITS8 0x0c
#define I8251_MODE_BAUD 0x03
#define I8251_MODE_SYNC 0x00
#define I8251_AMODE_BAUD1 0x01
#define I8251_AMODE_BAUD16 0x02
#define I8251_AMODE_BAUD64 0x03
#define I8251_SMODE_ESD 0x40
#define I8251_SMODE_SCS 0x80
#define I8251_CMD_EH 0x80
#define I8251_CMD_IR 0x40
#define I8251_CMD_RTS 0x20
#define I8251_CMD_ER 0x10
#define I8251_CMD_SBRK 0x08
#define I8251_CMD_RXE 0x04
#define I8251_CMD_DTR 0x02
#define I8251_CMD_TXEN 0x01
#define I8251_ST_DSR 0x80
#define I8251_ST_SYNBRK 0x40
#define I8251_ST_FE 0x20
#define I8251_ST_OE 0x10
#define I8251_ST_PE 0x08
#define I8251_ST_TXEMPTY 0x04
#define I8251_ST_RXRDY 0x02
#define I8251_ST_TXRDY 0x01
typedef struct i8251 {
PNP_INFO pnp;
DEVICE* dev; /* backlink to device */
t_stat (*write)(struct i8251* chip,int port,uint32 value);
t_stat (*read)(struct i8251* chip,int port,uint32* value);
t_stat (*reset)(struct i8251* chip);
t_stat (*txint)(struct i8251* chip);
t_stat (*rxint)(struct i8251* chip);
UNIT* in;
UNIT* out;
SERMUX* mux;
int init;
int mode;
int sync1;
int sync2;
int cmd;
int ibuf;
int obuf;
int status;
int bitmask;
t_bool oob; /* out-of-band=1 will allow a console to receive CTRL-E even when receiver is disabled */
int crlf; /* CRLF state machine to suppress NUL bytes */
} I8251;
/* default handlers */
extern t_stat i8251_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
extern t_stat i8251_write(I8251* chip,int port,uint32 value);
extern t_stat i8251_read(I8251* chip,int port,uint32* value);
extern t_stat i8251_reset(I8251* chip);
/* Debug flags */
#define DBG_UART_RD (1 << 0)
#define DBG_UART_WR (1 << 1)
#define DBG_UART_IRQ (1 << 2)
extern DEBTAB i8251_dt[];
/*****************************************************************************************
* 8253 TIMER
*****************************************************************************************/
/*forward*/ struct i8253;
typedef struct {
t_stat (*call)(struct i8253* chip,int rw,uint32* src);
int state; /* the current output state (latching, MSB/LSB out */
int mode; /* programmed mode */
int32 latch; /* the latched value of count */
int32 divider; /* programmed divider value */
int32 count; /* the real count value as calculated by rcall callback */
} I8253CNTR;
typedef struct i8253 {
PNP_INFO pnp;
DEVICE* dev; /* backlink to device */
UNIT* unit; /* backlink to unit */
t_stat (*reset)(struct i8253* chip);
t_stat (*ckmode)(struct i8253* chip, uint32 value);
I8253CNTR cntr[3];
int init;
} I8253;
#define I8253_SCMASK 0xc0
#define I8253_SC0 0x00
#define I8253_SC1 0x40
#define I8253_SC2 0x80
#define I8253_RLMASK 0x30
#define I8253_LATCH 0x00
#define I8253_LSB 0x10
#define I8253_MSB 0x20
#define I8253_BOTH 0x30
#define I8253_MODEMASK 0xe0
#define I8253_MODE0 0x00
#define I8253_MODE1 0x02
#define I8253_MODE2 0x04
#define I8253_MODE2a 0x0c
#define I8253_MODE3 0x06
#define I8253_MODE3a 0x0e
#define I8253_MODE4 0x08
#define I8253_MODE5 0x0a
#define I8253_MODEBIN 0x00
#define I8253_MODEBCD 0x01
#define I8253_ST_LSBNEXT 0x01
#define I8253_ST_MSBNEXT 0x02
#define I8253_ST_LATCH 0x08
/* default handlers */
extern t_stat i8253_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
extern t_stat i8253_reset(I8253* chip);
/* Debug flags */
#define DBG_TMR_RD (1 << 0)
#define DBG_TMR_WR (1 << 1)
extern DEBTAB i8253_dt[];
/****************************************************************************************
* upd765 FDC chip
***************************************************************************************/
#define I8272_MAX_DRIVES 4
#define I8272_MAX_SECTOR 26
#define I8272_MAX_SECTOR_SZ 8192
/* 2^(7 + I8272_MAX_N) == I8272_MAX_SECTOR_SZ */
#define I8272_MAX_N 6
#define I8272_FDC_MSR 0 /* R=FDC Main Status Register, W=Drive Select Register */
#define I8272_FDC_DATA 1 /* R/W FDC Data Register */
typedef struct {
UNIT *uptr;
DISK_INFO *imd;
uint8 ntracks; /* number of tracks */
uint8 nheads; /* number of heads */
uint32 sectsize; /* sector size, not including pre/postamble */
uint8 track; /* Current Track */
uint8 ready; /* Is drive ready? */
} I8272_DRIVE_INFO;
typedef enum i8272state {
S_CMD=1, S_CMDREAD, S_EXEC, S_DATAWRITE, S_SECWRITE, S_SECREAD, S_DATAREAD, S_RESULT
} I8272_STATE;
typedef struct i8272 {
PNP_INFO pnp; /* Plug-n-Play Information */
DEVICE* dev; /* backlink to device */
t_stat (*write)(struct i8272* chip,int port,uint32 data);
t_stat (*read)(struct i8272* chip,int port,uint32* data);
t_stat (*reset)(struct i8272* chip);
void (*seldrv)(struct i8272* chip,int seldrv);
void (*irq)(struct i8272* chip,int delay);
I8272_STATE fdc_state; /* internal state machine */
uint32 fdc_dma_addr;/* DMA Transfer Address */
uint8 fdc_msr; /* 8272 Main Status Register */
uint8 fdc_nd; /* Non-DMA Mode 1=Non-DMA, 0=DMA */
uint8 fdc_head; /* H Head Number */
uint8 fdc_sector; /* R Record (Sector) */
uint8 fdc_sec_len; /* N Sector Length in controller units (2^(7+fdc_sec_len)) */
uint8 fdc_eot; /* EOT End of Track (Final sector number of cyl) */
uint8 fdc_gap; /* GAP Length */
uint8 fdc_dtl; /* DTL Data Length */
uint8 fdc_mt; /* Multiple sectors */
uint8 fdc_mfm; /* MFM mode */
uint8 fdc_sk; /* Skip Deleted Data */
uint8 fdc_hds; /* Head Select */
uint8 fdc_seek_end; /* Seek was executed successfully */
int fdc_secsz; /* N Sector Length in bytes: 2^(7 + fdc_sec_len), fdc_sec_len <= I8272_MAX_N */
int fdc_nd_cnt; /* read/write count in non-DMA mode, -1 if start read */
uint8 fdc_sdata[I8272_MAX_SECTOR_SZ]; /* sector buffer */
uint8 fdc_fault; /* error code passed from some commands to sense_int */
uint8 cmd_cnt; /* command read count */
uint8 cmd[10]; /* Storage for current command */
uint8 cmd_len; /* FDC Command Length */
uint8 result_cnt; /* result emit count */
uint8 result[10]; /* Result data */
uint8 result_len; /* FDC Result Length */
uint8 idcount; /* used to cycle sector numbers during ReadID */
uint8 irqflag; /* set by interrupt, cleared by I8272_SENSE_INTERRUPT */
uint8 fdc_curdrv; /* Currently selected drive */
I8272_DRIVE_INFO drive[I8272_MAX_DRIVES];
} I8272;
extern t_stat i8272_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
extern t_stat i8272_write(I8272* chip, int addr, uint32 value);
extern t_stat i8272_read(I8272* chip,int addr,uint32* value);
extern t_stat i8272_reset(I8272* chip);
extern void i8272_seldrv(I8272* chip,int drvnum);
extern t_stat i8272_abortio(I8272* chip);
extern t_stat i8272_finish(I8272* chip);
extern t_stat i8272_attach(UNIT *uptr, char *cptr);
extern t_stat i8272_detach(UNIT *uptr);
extern t_stat i8272_setDMA(I8272* chip, uint32 dma_addr);
/* Debug flags */
#define DBG_FD_ERROR (1 << 0)
#define DBG_FD_SEEK (1 << 1)
#define DBG_FD_CMD (1 << 2)
#define DBG_FD_RDDATA (1 << 3)
#define DBG_FD_WRDATA (1 << 4)
#define DBG_FD_STATUS (1 << 5)
#define DBG_FD_FMT (1 << 6)
#define DBG_FD_VERBOSE (1 << 7)
#define DBG_FD_IRQ (1 << 8)
#define DBG_FD_STATE (1 << 9)
#define DBG_FD_IMD (1 << 10)
#define DBG_FD_DATA (1 << 11)
extern DEBTAB i8272_dt[];
extern DEVICE* i8272_dev;
/* moved from i8272.c */
#define UNIT_V_I8272_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_I8272_WLK (1 << UNIT_V_I8272_WLK)
#define UNIT_V_I8272_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
#define UNIT_I8272_VERBOSE (1 << UNIT_V_I8272_VERBOSE)
#define I8272_CAPACITY (77*2*16*256) /* Default Micropolis Disk Capacity */
#define I8272_CAPACITY_SSSD (77*1*26*128) /* Single-sided Single Density IBM Diskette1 */
/*****************************************************************************************
* 8255 PARPORT
*****************************************************************************************/
typedef struct i8255 {
PNP_INFO pnp;
DEVICE* dev; /* backlink to device */
t_stat (*write)(struct i8255* chip,int port,uint32 data);
t_stat (*read)(struct i8255* chip,int port,uint32* data);
t_stat (*reset)(struct i8255* chip);
t_stat (*calla)(struct i8255* chip,int rw);
t_stat (*callb)(struct i8255* chip,int rw);
t_stat (*callc)(struct i8255* chip,int rw);
t_stat (*ckmode)(struct i8255* chip,uint32 data);
uint32 porta;
uint32 last_porta; /* for edge detection */
uint32 portb;
uint32 last_portb; /* for edge detection */
uint32 portc;
uint32 last_portc; /* for edge detection */
uint32 ctrl;
} I8255;
extern t_stat i8255_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
extern t_stat i8255_read(I8255* chip,int port,uint32* data);
extern t_stat i8255_write(I8255* chip,int port,uint32 data);
#define I8255_RISEEDGE(port,bit) ((chip->last_##port & bit)==0 && (chip->port & bit))
#define I8255_FALLEDGE(port,bit) ((chip->last_##port & bit) && (chip->port & bit)==0)
#define I8255_ISSET(port,bit) ((chip->port & (bit))==(bit))
#define I8255_ISCLR(port,bit) ((chip->port & (bit))==0)
/* debug flags */
#define DBG_PP_WRA (1<<0)
#define DBG_PP_WRB (1<<1)
#define DBG_PP_WRC (1<<2)
#define DBG_PP_RDA (1<<3)
#define DBG_PP_RDB (1<<4)
#define DBG_PP_RDC (1<<5)
#define DBG_PP_MODE (1<<6)
#endif /*CHIP_DEFS_H_*/

145
SAGE/i8251.c Normal file
View file

@ -0,0 +1,145 @@
/* sage_stddev.c: Standard devices for sage-II system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
22-Jan-10 HV Initial version
*/
#include "sim_defs.h"
#include "m68k_cpu.h"
#include "chip_defs.h"
static int i8251_bitmask[] = { 0x1f, 0x3f, 0x7f, 0xff };
/* Debug Flags */
DEBTAB i8251_dt[] = {
{ "READ", DBG_UART_RD },
{ "WRITE", DBG_UART_WR },
{ "IRQ", DBG_UART_IRQ },
{ NULL, 0 }
};
t_stat i8251_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
{
int port = ioh->offset;
I8251* chip = (I8251*)ioh->ctxt;
if (rw==MEM_WRITE) {
return chip->write ? chip->write(chip,port,*value) : i8251_write(chip,port,*value);
} else {
return chip->read ? chip->read(chip,port,value) : i8251_read(chip,port,value);
}
}
t_stat i8251_write(I8251* chip,int port,uint32 value)
{
int bits;
if (port==0) { /* data port */
chip->obuf = value & chip->bitmask;
TRACE_PRINT1(DBG_UART_WR,"WR DATA = 0x%02x",chip->obuf);
if (chip->init==3) { /* is fully initialized */
if ((chip->mode & I8251_MODE_BAUD)==I8251_MODE_SYNC) {
printf("i8251: sync mode not implemented\n");
return STOP_IMPL;
}
if (chip->cmd & I8251_CMD_TXEN) {
/* transmit data */
chip->status &= ~(I8251_ST_TXEMPTY|I8251_ST_TXRDY);
sim_activate(chip->out,chip->out->wait);
}
}
return SCPE_OK;
} else { /* control port */
switch (chip->init) {
case 0: /* expect mode word */
chip->mode = value;
TRACE_PRINT1(DBG_UART_WR,"WR MODE = 0x%02x",value);
chip->init = (value & I8251_MODE_BAUD)==I8251_MODE_SYNC ? 1 : 3;
bits = (chip->mode & I8251_AMODE_BITS) >> 2;
chip->bitmask = i8251_bitmask[bits];
break;
case 1: /* expect sync1 */
chip->sync1 = value;
TRACE_PRINT1(DBG_UART_WR,"WR SYNC1 = 0x%02x",value);
chip->init = 2;
break;
case 2: /* expect sync2 */
chip->sync2 = value;
TRACE_PRINT1(DBG_UART_WR,"WR SYNC2 = 0x%02x",value);
chip->init = 3;
break;
case 3: /* expect cmd word */
chip->cmd = value;
TRACE_PRINT1(DBG_UART_WR,"WR CMD = 0x%02x",value);
if (value & I8251_CMD_EH) {
printf("i8251: hunt mode not implemented\n");
return STOP_IMPL;
}
if (value & I8251_CMD_IR)
chip->init = 0;
if (value & I8251_CMD_ER)
chip->status &= ~(I8251_ST_FE|I8251_ST_OE|I8251_ST_PE);
if (value & I8251_CMD_SBRK)
printf("i8251: BREAK sent\n");
if (value & I8251_CMD_RXE) {
sim_activate(chip->in,chip->in->wait);
} else {
if (!chip->oob) sim_cancel(chip->in);
}
if (value & I8251_CMD_TXEN) {
if (!(chip->status & I8251_ST_TXEMPTY))
sim_activate(chip->out,chip->out->wait);
else {
chip->status |= I8251_ST_TXRDY;
if (chip->txint) chip->txint(chip);
}
} else {
chip->status &= ~I8251_ST_TXRDY;
sim_cancel(chip->out);
}
}
return SCPE_OK;
}
}
t_stat i8251_read(I8251* chip,int port,uint32* value)
{
if (port==0) { /* data read */
*value = chip->ibuf;
chip->status &= ~I8251_ST_RXRDY; /* mark read buffer as empty */
TRACE_PRINT1(DBG_UART_RD,"RD DATA = 0x%02x",*value);
} else { /* status read */
*value = chip->status & 0xff;
TRACE_PRINT1(DBG_UART_RD,"RD STATUS = 0x%02x",*value);
}
return SCPE_OK;
}
t_stat i8251_reset(I8251* chip)
{
chip->init = 0;
chip->oob = FALSE;
chip->crlf = 0;
return SCPE_OK;
}

143
SAGE/i8253.c Normal file
View file

@ -0,0 +1,143 @@
/* sage_stddev.c: Standard devices for sage-II system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
22-Jan-10 HV Initial version
*/
#include "sim_defs.h"
#include "m68k_cpu.h"
#include "chip_defs.h"
/* Debug Flags */
DEBTAB i8253_dt[] = {
{ "READ", DBG_TMR_RD },
{ "WRITE", DBG_TMR_WR },
{ NULL, 0 }
};
static char* rltype[] = { "latch","8bitL","8bitH", "16bit" };
t_stat i8253_write(I8253* chip, int addr, uint32 value)
{
I8253CNTR* cntr;
t_stat rc;
int num;
if (addr==3) { /* mode reg */
TRACE_PRINT(DBG_TMR_WR,(sim_deb,"WR MODE=%x (SC=%d RL=%s MODE=%d BCD=%d)",
value,(value>>6)&3,rltype[(value>>4)&3],(value>>1)&7,value&1));
if (chip->ckmode && (rc=chip->ckmode(chip,value))!= SCPE_OK) return rc;
num = (value & I8253_SCMASK)>>6;
cntr = &chip->cntr[num];
if ((value & I8253_RLMASK)==I8253_LATCH) {
/* calculate current value of count */
cntr->latch = cntr->count; /* latch it */
cntr->state |= I8253_ST_LATCH;
} else {
cntr->mode = value;
cntr->state = (value & I8253_RLMASK)==I8253_MSB ? I8253_ST_MSBNEXT : I8253_ST_LSBNEXT;
}
} else { /* write dividers */
cntr = &chip->cntr[addr];
switch (cntr->mode & I8253_RLMASK) {
case I8253_MSB:
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIVMSB=%x",addr,value);
cntr->divider = (cntr->divider & 0x00ff) | ((value<<8) | 0xff);
cntr->state &= ~I8253_ST_LATCH;
cntr->count = cntr->divider;
break;
case I8253_LSB:
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIVLSB=%x",addr,value);
cntr->divider = (cntr->divider & 0xff00) | (value | 0xff);
cntr->state &= ~I8253_ST_LATCH;
cntr->count = cntr->divider;
break;
case I8253_BOTH:
if (cntr->state & I8253_ST_MSBNEXT) {
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIV16MSB=%x",addr,value);
cntr->divider = (cntr->divider & 0x00ff) | ((value & 0xff)<<8);
cntr->state = I8253_ST_LSBNEXT; /* reset latch mode and MSB bit */
cntr->count = cntr->divider;
} else {
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIV16LSB=%x",addr,value);
cntr->divider = (cntr->divider & 0xff00) | (value & 0xff);
cntr->state = I8253_ST_MSBNEXT; /* reset latch mode and LSB bit */
}
default:
break;
}
/* execute a registered callback before returning result */
if (cntr->call && (rc=(*cntr->call)(chip,1,&value)) != SCPE_OK) return rc;
}
return SCPE_OK;
}
t_stat i8253_read(I8253* chip,int addr,uint32* value)
{
t_stat rc;
I8253CNTR* cntr = &chip->cntr[addr];
int32 src = cntr->state & I8253_ST_LATCH ? cntr->latch : cntr->count;
if (cntr->call && (rc=(*cntr->call)(chip,0,(uint32*)&src)) != SCPE_OK) return rc;
switch (cntr->mode & I8253_RLMASK) {
case I8253_MSB:
src >>= 8;
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNTMSB=%x",addr,src&0xff);
cntr->state &= ~I8253_ST_LATCH;
break;
case I8253_LSB:
cntr->state &= ~I8253_ST_LATCH;
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNTLSB=%x",addr,src&0xff);
break;
case I8253_BOTH:
if (cntr->state & I8253_ST_MSBNEXT) {
src >>= 8; cntr->state = I8253_ST_LSBNEXT; /* reset latch mode and MSB bit */
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNT16MSB=%x",addr,src&0xff);
} else {
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNT16LSB=%x",addr,src&0xff);
cntr->state |= I8253_ST_MSBNEXT; /* does not reset latch mode if set */
}
break;
default:
return SCPE_OK;
}
*value = src & 0xff;
return SCPE_OK;
}
t_stat i8253_reset(I8253* chip)
{
int i;
for (i=0; i<3; i++) chip->cntr[i].state = 0;
return SCPE_OK;
}
t_stat i8253_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
{
int port = ioh->offset;
I8253* chip = (I8253*)ioh->ctxt;
return rw==MEM_WRITE ? i8253_write(chip,port,*value) : i8253_read(chip,port,value);
}

106
SAGE/i8255.c Normal file
View file

@ -0,0 +1,106 @@
/* i8255.c: helper for 8255 implementation
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
14-Mar-10 HV Initial version
*/
#include "sim_defs.h"
#include "m68k_cpu.h"
#include "chip_defs.h"
static t_stat i8255_error(const char* err)
{
printf("I8255: Missing method '%s'\n",err);
return STOP_IMPL;
}
t_stat i8255_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
{
int port = ioh->offset;
I8255* chip = (I8255*)ioh->ctxt;
if (rw==MEM_WRITE) {
return chip->write ? chip->write(chip,port,*value) : i8255_error("write");
} else {
return chip->read ? chip->read(chip,port,value) : i8255_error("read");
}
}
t_stat i8255_read(I8255* chip,int port,uint32* data)
{
t_stat rc;
switch (port) {
case 0:
if (chip->calla && (rc=(*chip->calla)(chip,0)) != SCPE_OK) return rc;
*data = chip->porta;
return SCPE_OK;
case 1:
if (chip->callb && (rc=(*chip->callb)(chip,0)) != SCPE_OK) return rc;
*data = chip->portb;
return SCPE_OK;
case 2:
if (chip->callc && (rc=(*chip->callc)(chip,0)) != SCPE_OK) return rc;
*data = chip->portc;
return SCPE_OK;
case 3:
*data = 0xff; /* undefined */
return SCPE_OK;
default:
return SCPE_IERR;
}
}
t_stat i8255_write(I8255* chip,int port,uint32 data)
{
t_stat rc;
uint32 bit;
switch(port) {
case 0: /*port a*/
chip->last_porta = chip->porta;
chip->porta = data;
return chip->calla ? (*chip->calla)(chip,1) : SCPE_OK;
case 1: /*port b*/
chip->last_portb = chip->portb;
return chip->callb ? (*chip->callb)(chip,1) : SCPE_OK;
case 2:
chip->last_portc = chip->portc;
chip->portc = data & 0xff;
return chip->callc ? (*chip->callc)(chip,1) : SCPE_OK;
case 3:
if (data & 0x80) { /* mode set mode */
if (chip->ckmode && (rc=chip->ckmode(chip,data))) return rc;
chip->ctrl = data & 0x7f;
return SCPE_OK;
} else { /* bit set mode */
chip->last_portc = chip->portc;
bit = 1 << ((data & 0x0e)>>1);
TRACE_PRINT2(DBG_PP_WRC,"WR PORTC %s bit=%x",data&1 ? "SET": "CLR",bit);
if (data & 1) chip->portc |= bit; else chip->portc &= ~bit;
chip->portc &= 0xff;
return chip->callc ? (*chip->callc)(chip,1) : SCPE_OK;
}
default:
return SCPE_IERR;
}
}

244
SAGE/i8259.c Normal file
View file

@ -0,0 +1,244 @@
/* chip_i8259.c: system independent implementation of PIC chip
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
22-Jan-10 HV Initial version
03-Jun-10 HV Repair POLL function (defective FDC interrupt handling in SAGEBIOS)
*/
#include "sim_defs.h"
#include "m68k_cpu.h"
#include "chip_defs.h"
/* Debug Flags */
DEBTAB i8259_dt[] = {
{ "READ", DBG_PIC_RD },
{ "WRITE", DBG_PIC_WR },
{ "IRQIN", DBG_PIC_II },
{ "IRQOUT", DBG_PIC_IO },
{ NULL, 0 }
};
static int32 priomask[] = { 0x0000,0x4000,0x6000,0x7000,0x7800,0x7c00,0x7e00,0x7f00 };
t_stat i8259_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
{
int port = ioh->offset;
I8259* chip = (I8259*)ioh->ctxt;
if (rw==MEM_WRITE) {
return chip->write ? chip->write(chip,port,*value) : i8259_write(chip,port,*value);
} else {
return chip->read ? chip->read(chip,port,value) : i8259_read(chip,port,value);
}
}
t_stat i8259_write(I8259* chip,int addr,uint32 value)
{
int i, bit;
#if 0
TRACE_PRINT2(DBG_PIC_WR,"WR addr=%d data=0x%x",addr,value);
#endif
if (addr==1) {
switch (chip->state) {
default:
case 0: /* after reset */
printf("PIC: write addr=1 without initialization\n");
return SCPE_IOERR;
case 1: /* expect ICW2 */
TRACE_PRINT2(DBG_PIC_WR,"WR ICW2: addr=%d data=0x%x",addr,value);
chip->icw2 = value;
if (chip->icw1 & I8259_ICW1_SNGL) {
chip->state = (chip->icw1 & I8259_ICW1_IC4) ? 4 : 5;
} else {
/* attempt to program cascade mode */
printf("PIC: attempt to program chip for cascade mode - not wired for this!\n");
chip->state = 0;
return SCPE_IOERR;
}
break;
case 4: /* expect ICW4 */
TRACE_PRINT2(DBG_PIC_WR,"WR ICW4 addr=%d data=0x%x",addr,value);
chip->icw4 = value;
if (chip->icw4 & I8259_ICW4_AEOI) {
printf("PIC: attempt to program chip for AEOI mode - not wired for this!\n");
return SCPE_IOERR;
}
if (chip->icw4 & I8259_ICW4_BUF) {
printf("PIC: attempt to program chip for buffered mode - not wired for this!\n");
return SCPE_IOERR;
}
if (chip->icw4 & I8259_ICW4_SFNM) {
printf("PIC: attempt to program chip for spc nested mode - not wired for this!\n");
return SCPE_IOERR;
}
chip->state = 5;
break;
case 5: /* ready to accept interrupt requests and ocw commands */
/* ocw1 */
TRACE_PRINT2(DBG_PIC_WR,"WR IMR addr=%d data=0x%x",addr,value);
chip->imr = value;
break;
}
} else {
if (value & I8259_ICW1) { /* state initialization sequence */
TRACE_PRINT2(DBG_PIC_WR,"WR ICW1 addr=%d data=0x%x",addr,value);
chip->icw1 = value;
chip->state = 1;
chip->rmode = 0;
chip->prio = 7;
if ((chip->icw1 & I8259_ICW1_IC4)==0) chip->icw4 = 0;
return SCPE_OK;
} else { /* ocw2 and ocw3 */
if (value & I8259_OCW3) { /* ocw3 */
TRACE_PRINT2(DBG_PIC_WR,"WR OCW3 addr=%d data=0x%x",addr,value);
if (value & I8259_OCW3_ESMM) {
printf("PIC: ESMM not yet supported\n");
return STOP_IMPL;
}
if (value & I8259_OCW3_POLL) {
chip->rmode |= 2;
return SCPE_OK;
}
if (value & I8259_OCW3_RR)
chip->rmode = (value & I8259_OCW3_RIS) ? 1 /*isr*/ : 0; /* irr */
} else { /* ocw2 */
TRACE_PRINT2(DBG_PIC_WR,"WR OCW2 addr=%d data=0x%x",addr,value);
switch (value & I8259_OCW2_MODE) {
case 0xa0: /* rotate on nospecific eoi */
case 0x20: /* nonspecific eoi */
bit = 1 << (7 - chip->prio);
for (i=0; i<7; i++) {
if (chip->isr & bit) break;
bit = bit << 1; if (bit==0x100) bit = 1;
}
chip->isr &= ~bit; break;
if ((value & I8259_OCW2_MODE) == 0xa0) {
chip->prio = 7 - i + chip->prio; if (chip->prio>7) chip->prio -= 8;
}
break;
case 0xe0: /* rotate on specific eoi */
chip->prio = 7 - (value & 7) + chip->prio; if (chip->prio>7) chip->prio -= 8;
/*fallthru*/
case 0x60: /* specific eoi */
bit = 1 << (value & 7);
chip->isr = chip->isr & ~bit & 0xff;
break;
case 0x80: /* rotate in autoeoi (set) */
case 0x00: /* rotate in autoeoi (clear) */
printf("PIC: AEOI not supported\n");
return SCPE_IOERR;
case 0xc0: /* set prio */
chip->prio = value & 7;
return SCPE_OK;
case 0x40: /* nop */
break;
default:
return SCPE_IERR;
}
}
}
}
return SCPE_OK;
}
t_stat i8259_read(I8259* chip,int addr, uint32* value)
{
int i, bit, num;
if (addr) {
*value = chip->imr;
} else {
switch (chip->rmode) {
case 0:
TRACE_PRINT2(DBG_PIC_RD,"Read IRR addr=%d data=0x%x",addr,chip->irr);
*value = chip->irr; break;
case 1:
TRACE_PRINT2(DBG_PIC_RD,"Read ISR addr=%d data=0x%x",addr,chip->irr);
*value = chip->isr; break;
case 2:
case 3:
TRACE_PRINT2(DBG_PIC_RD,"Read POLL addr=%d data=0x%x",addr,chip->irr);
num = chip->prio;
bit = 1 << chip->prio;
for (i=0; i<8; i++,num--) {
if (chip->isr & bit) {
*value = 0x80 | (num & 7);
TRACE_PRINT2(DBG_PIC_RD,"Read POLL addr=%d data=0x%x",addr,*value);
return SCPE_OK;
}
bit >>= 1;
if (bit==0) { bit = 0x80; num = 7; }
}
chip->rmode &= ~2;
}
}
#if 0
TRACE_PRINT2(DBG_PIC_RD,"Read addr=%d data=0x%x",addr,*value);
#endif
return SCPE_OK;
}
t_stat i8259_raiseint(I8259* chip,int level)
{
int32 bit, isr, myprio;
TRACE_PRINT1(DBG_PIC_II,"Request INT level=%d",level);
if (chip->state != 5) return SCPE_OK; /* not yet initialized, ignore interrupts */
bit = 1<<level;
if (chip->imr & bit) return SCPE_OK; /* inhibited */
chip->isr = (chip->isr | bit) & 0xff; /* request this interrupt level */
/* bit7=prio7 => bitN = prioN
bit7=prio6 => bitN = prioN-1
...
bit7=prio0 => bitN = prioN-7
*/
isr = (chip->isr<<8) | chip->isr; /* simple rotation */
isr = isr << (7-level); /* shift level bit into bit 15 */
myprio = chip->prio - 7 + level; if (myprio < 0) myprio += 8;
if (!(isr & priomask[myprio])) { /* higher interrupt is pending */
if (chip->autoint) {
TRACE_PRINT1(DBG_PIC_IO,"Raise AUTOINT level=%d",chip->intlevel);
return m68k_raise_autoint(chip->intlevel);
} else {
TRACE_PRINT2(DBG_PIC_IO,"Raise VECTORINT level=%d vector=%x",chip->intlevel,chip->intvector);
return m68k_raise_vectorint(chip->intlevel,chip->intvector);
}
}
return SCPE_OK;
}
t_stat i8259_reset(I8259* chip)
{
chip->autoint = TRUE;
chip->intlevel = 1;
chip->intvector = 0;
chip->state = 0;
chip->rmode = 0;
chip->imr = 0;
return SCPE_OK;
}

1058
SAGE/i8272.c Normal file

File diff suppressed because it is too large Load diff

3352
SAGE/m68k_cpu.c Normal file

File diff suppressed because it is too large Load diff

252
SAGE/m68k_cpu.h Normal file
View file

@ -0,0 +1,252 @@
/* 68k_cpu.c: 68k-CPU simulator for sage-II system
Copyright (c) 2009, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#ifndef M68K_CPU_H_
#define M68K_CPU_H_ 0
#include "sim_defs.h"
/* define this o 1 for adding debugging code */
#define DBG_MSG 1
#if !defined(HAVE_INT64)
#error Fix me, I need 64 bit data types!
#endif
/* these must be set in the system-specific CPU reset */
extern UNIT* m68kcpu_unit;
extern DEVICE* m68kcpu_dev;
/* implemented in m68k_cpu.c */
extern REG m68kcpu_reg[];
/* debug flags */
#define DBG_CPU_EXC (1 << 0)
#define DBG_CPU_PC (1 << 1)
#define DBG_CPU_INT (1 << 2)
#define DBG_CPU_CTRACE (1 << 3)
#define DBG_CPU_BTRACE (1 << 4)
#define DBG_CPU_CUSTOM1 (1 << 5) /* reserved for custom debugging */
#define DBG_CPU_CUSTOM2 (1 << 6) /* reserved for custom debugging */
extern FILE* sim_deb;
extern DEBTAB m68kcpu_dt[];
#if DBG_MSG==1
#define IFDEBUG(flag,func) if ((m68kcpu_dev->dctrl & flag) && sim_deb) { (void)(func); fflush(sim_deb); }
#else
#define IFDEBUG(flag,func)
#endif
#define SIM_EMAX 16 /* ? */
#define MAXMEMORY (256*256*256) /* 2^24 bytes */
#define MINMEMORY (256*256) /* reserve 64k by default */
#define MEMORYSIZE (m68kcpu_unit->capac) /* actual memory size */
#define KB 1024 /* kilobyte */
/* simulator stop codes */
#define STOP_IBKPT 1 /* pc breakpoint */
#define STOP_MEM 2 /* memory breakpoint */
#define STOP_ERROP 3 /* invalid opcode, normally exception 4 */
#define STOP_ERRIO 4 /* invalid I/O address, normally exception 2 */
#define STOP_ERRADR 5 /* invalid memory address, normally exception 3 */
#define STOP_IMPL 6 /* not yet implemented (should disappear) */
#define SIM_ISIO 7 /* internal indicator that I/O dispatch is required */
#define SIM_NOMEM 8 /* allows to signal that there is no memory at that location */
#define STOP_PCIO 9 /* code error, PC steps on I/O address */
#define STOP_PRVIO 10 /* internal indicator: privileged instruction */
#define STOP_TRACE 11 /* halt on trace */
#define STOP_HALT 12 /* STOP instruction */
#define STOP_DBF 13 /* double bus fault */
#define STOP_OFFLINE 14 /* printer offline */
#define UNIT_CPU_M_TYPE 017
#define UNIT_CPU_V_TYPE (UNIT_V_UF+0) /* CPUTYPE */
#define UNIT_CPU_TYPE (1 << UNIT_CPU_V_CPU)
#define UNIT_CPU_V_EXC (UNIT_V_UF+4) /* halt on exception 2..4 */
#define UNIT_CPU_EXC (1 << UNIT_CPU_V_EXC)
#define UNIT_CPU_V_STOP (UNIT_V_UF+5) /* halt on STOP instruction */
#define UNIT_CPU_STOP (1 << UNIT_CPU_V_STOP)
#define UNIT_CPU_V_PRVIO (UNIT_V_UF+6) /* halt on privilege violation */
#define UNIT_CPU_PRVIO (1 << UNIT_CPU_V_PRVIO)
#define UNIT_CPU_V_TRACE (UNIT_V_UF+7) /* halt on TRACE exception */
#define UNIT_CPU_TRACE (1 << UNIT_CPU_V_TRACE)
#define UNIT_CPU_V_FPU (UNIT_V_UF+8) /* has FPU */
#define UNIT_CPU_FPU (1 << UNIT_CPU_V_FPU)
#define UNIT_CPU_V_MMU (UNIT_V_UF+9) /* has MMU */
#define UNIT_CPU_MMU (1 << UNIT_CPU_V_MMU)
#define UNIT_CPU_V_MSIZE (UNIT_V_UF+10) /* set memsize */
#define UNIT_CPU_MSIZE (1 << UNIT_CPU_V_MSIZE)
#define UNIT_CPU_V_FREE (UNIT_V_UF+11) /* next free bit */
/* the various CPUs */
#define UNIT_CPUTYPE_MASK (UNIT_CPU_M_TYPE << UNIT_CPU_V_TYPE)
#define CPU_TYPE_68000 (0 << UNIT_CPU_V_TYPE)
#define CPU_TYPE_68008 (1 << UNIT_CPU_V_TYPE)
#define CPU_TYPE_68010 (2 << UNIT_CPU_V_TYPE) /* not yet! */
#define CPU_TYPE_68020 (3 << UNIT_CPU_V_TYPE) /* not yet! */
#define CPU_TYPE_68030 (4 << UNIT_CPU_V_TYPE) /* not yet! */
extern uint8 *M;
extern int16 cputype;
extern t_addr saved_PC;
#define PCX saved_PC
/* breakpoint space for data accesses (R=read, W=write) */
#define E_BKPT_SPC (0)
#define R_BKPT_SPC (1<<SIM_BKPT_V_SPC)
#define W_BKPT_SPC (2<<SIM_BKPT_V_SPC)
/* IR 7-6 bits */
#define SZ_BYTE 0
#define SZ_WORD 1
#define SZ_LONG 2
#define SZ_SPEC 3
/* functions to access memory
* xxxxPx access physical memory
* xxxxVx access virtual memory using MMU; if no MMU xxxxVX == xxxxPX
* xxxxxB = byte, xxxxxW = 16 bit word, xxxxxL = 32 bit word
*/
#define BMASK 0x000000ff
#define BLMASK BMASK
#define BHMASK 0x0000ff00
#define WMASK 0x0000ffff
#define WLMASK WMASK
#define WHMASK 0xffff0000
#define LMASK 0xffffffff
extern t_addr addrmask;
#define MEM_READ 0
#define MEM_WRITE 1
/* I/O handler block */
#define IO_READ 0
#define IO_WRITE 1
struct _iohandler {
void* ctxt;
t_addr port;
t_addr offset;
UNIT* u;
t_stat (*io)(struct _iohandler* ioh,uint32* value,uint32 rw,uint32 mask);
struct _iohandler* next;
};
typedef struct _iohandler IOHANDLER;
typedef struct {
uint32 mem_base; /* Memory Base Address */
uint32 mem_size; /* Memory Address space requirement */
uint32 io_base; /* I/O Base Address */
uint32 io_size; /* I/O Address Space requirement */
uint32 io_incr; /* I/O Address increment */
} PNP_INFO;
extern t_stat add_iohandler(UNIT* u,void* ctxt,
t_stat (*io)(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask));
extern t_stat del_iohandler(void* ctxt);
extern t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc);
extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc);
/* public memory access routines */
extern t_stat ReadPB(t_addr a, uint32* val);
extern t_stat ReadPW(t_addr a, uint32* val);
extern t_stat ReadPL(t_addr a, uint32* val);
extern t_stat WritePB(t_addr a, uint32 val);
extern t_stat WritePW(t_addr a, uint32 val);
extern t_stat WritePL(t_addr a, uint32 val);
extern t_stat ReadVB(t_addr a, uint32* val);
extern t_stat ReadVW(t_addr a, uint32* val);
extern t_stat ReadVL(t_addr a, uint32* val);
extern t_stat WriteVB(t_addr a, uint32 val);
extern t_stat WriteVW(t_addr a, uint32 val);
extern t_stat WriteVL(t_addr a, uint32 val);
extern t_stat (*TranslateAddr)(t_addr in,t_addr* out,IOHANDLER** ioh,int rw,int fc,int dma);
extern t_stat m68k_translateaddr(t_addr in,t_addr* out,IOHANDLER** ioh,int rw,int fc,int dma);
extern t_stat (*Mem)(t_addr a,uint8** mem);
extern t_stat m68k_mem(t_addr a,uint8** mem);
/* cpu_mod for alternative implementations */
extern t_stat m68k_set_cpu(UNIT *uptr, int32 value, char *cptr, void *desc);
extern t_stat m68k_show_cpu(FILE* st,UNIT *uptr, int32 value, void *desc);
extern t_stat m68k_set_size(UNIT *uptr, int32 value, char *cptr, void *desc);
extern t_stat m68k_set_fpu(UNIT *uptr, int32 value, char *cptr, void *desc);
extern t_stat m68k_set_nofpu(UNIT *uptr, int32 value, char *cptr, void *desc);
extern t_stat m68kcpu_set_flag(UNIT *uptr, int32 value, char *cptr, void *desc);
extern t_stat m68kcpu_set_noflag(UNIT *uptr, int32 value, char *cptr, void *desc);
extern t_stat m68kcpu_reset(DEVICE* dptr);
extern t_stat m68kcpu_ex(t_value* eval_array, t_addr addr, UNIT *uptr, int32 switches);
extern t_stat m68kcpu_dep(t_value value, t_addr addr, UNIT* uptr, int32 switches);
extern t_stat m68kcpu_boot(int32 unitno,DEVICE* dptr);
extern t_stat m68k_ioinit();
extern t_stat m68kcpu_peripheral_reset();
extern t_stat m68k_alloc_mem();
extern t_stat m68k_raise_vectorint(int level,int vector);
extern t_stat m68k_raise_autoint(int level);
#define XFMT "0x%08x"
#define SFMT "$%x"
extern char* m68k_getsym(t_addr val,const char* fmt, char* outbuf);
/* overloadable callbacks */
extern void (*m68kcpu_trapcallback)(DEVICE* cpudev,int trapnum);
/* standard MTAB declarations for most 68K CPUs */
#define M68KCPU_STDMOD \
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68000, "", "68000", &m68k_set_cpu, &m68k_show_cpu, "68000" },\
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68008, "", "68008", &m68k_set_cpu, &m68k_show_cpu, "68008" },\
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68010, "", "68010", &m68k_set_cpu, &m68k_show_cpu, "68010" },\
{ UNIT_CPU_MSIZE, (1u << 16), NULL, "64K", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 17), NULL, "128K", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 18), NULL, "256K", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 19), NULL, "512K", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 20), NULL, "1M", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 21), NULL, "2M", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 22), NULL, "4M", &m68k_set_size },\
{ UNIT_CPU_MSIZE, (1u << 23), NULL, "8M", &m68k_set_size },\
{ UNIT_CPU_EXC, UNIT_CPU_EXC, "halt on EXC", "EXC", &m68kcpu_set_flag },\
{ UNIT_CPU_EXC, 0, "no EXC", NULL, NULL },\
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_EXC, NULL, "NOEXC", &m68kcpu_set_noflag },\
{ UNIT_CPU_STOP, UNIT_CPU_STOP, "halt on STOP", "STOP", &m68kcpu_set_flag },\
{ UNIT_CPU_STOP, 0, "no STOP", NULL, NULL },\
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_STOP, NULL, "NOSTOP", &m68kcpu_set_noflag },\
{ UNIT_CPU_PRVIO, UNIT_CPU_PRVIO, "halt on PRVIO", "PRVIO", &m68kcpu_set_flag },\
{ UNIT_CPU_PRVIO, 0, "no PRVIO", NULL, NULL },\
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_PRVIO, NULL, "NOPRVIO", &m68kcpu_set_noflag },\
{ UNIT_CPU_TRACE, UNIT_CPU_TRACE, "halt on TRACE", "TRACE", &m68kcpu_set_flag },\
{ UNIT_CPU_TRACE, 0, "no TRACE", NULL, NULL },\
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_TRACE, NULL, "NOTRACE", &m68kcpu_set_noflag }
#if 0
,{ UNIT_CPU_FPU, UNIT_CPU_FPU, "FPU", "FPU", &m68k_set_fpu },
{ UNIT_CPU_FPU, 0, "no FPU", NULL, NULL },
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_FPU, NULL, "NOFPU", &m68k_set_nofpu },
#endif
#endif

425
SAGE/m68k_mem.c Normal file
View file

@ -0,0 +1,425 @@
/* m68k_mem.c: memory handling for m68k_cpu
Copyright (c) 2009, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
20-Dec-09 HV Rewrite memory handler for MMU and noncontiguous memory
*/
#include "m68k_cpu.h"
#include <ctype.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#endif
/* io hash */
#define IOHASHSIZE 97 /* must be prime */
#define MAKEIOHASH(p) (p % IOHASHSIZE)
static IOHANDLER** iohash = NULL;
/*
* memory
*/
uint8* M = 0;
t_addr addrmask = 0xffffffff;
int m68k_fcode = 0;
int m68k_dma = 0;
#if 0
/* TODO */
t_stat m68k_set_mmu(UNIT *uptr, int32 value, char *cptr, void *desc)
{
uptr->flags |= value;
/* TODO initialize the MMU */
TranslateAddr = &m68k_translateaddr;
return SCPE_OK;
}
t_stat m68k_set_nommu(UNIT *uptr, int32 value, char *cptr, void *desc)
{
uptr->flags &= ~value;
/* initialize NO MMU */
TranslateAddr = &m68k_translateaddr;
return SCPE_OK;
}
#endif
/* I/O dispatcher
*
* I/O devices are implemented this way:
* a unit will register its own I/O addresses together with its handler
* in a hash which allows simple translation of physical addresses
* into units in the ReadPx/WritePx routines.
* These routines call the iohandler entry on memory mapped read/write.
* The handler has the option to enqueue an event for its unit for
* asynchronous callback, e.g. interrupt processing
*/
t_stat m68k_ioinit()
{
if (iohash == NULL) {
iohash = (IOHANDLER**)calloc(IOHASHSIZE,sizeof(IOHANDLER*));
if (iohash == NULL) return SCPE_MEM;
}
return SCPE_OK;
}
t_stat add_iohandler(UNIT* u,void* ctxt,
t_stat (*io)(struct _iohandler* ioh,uint32* value,uint32 rw,uint32 mask))
{
PNP_INFO* pnp = (PNP_INFO*)ctxt;
IOHANDLER* ioh;
uint32 i,k;
if (!pnp) return SCPE_IERR;
for (k=i=0; i<pnp->io_size; i+=pnp->io_incr,k++) {
t_addr p = (pnp->io_base+i) & addrmask;
t_addr idx = MAKEIOHASH(p);
ioh = iohash[idx];
while (ioh != NULL && ioh->port != p) ioh = ioh->next;
if (ioh) continue; /* already registered */
// printf("Register IO for address %x offset=%d\n",p,k);
ioh = (IOHANDLER*)malloc(sizeof(IOHANDLER));
if (ioh == NULL) return SCPE_MEM;
ioh->ctxt = ctxt;
ioh->port = p;
ioh->offset = k;
ioh->u = u;
ioh->io = io;
ioh->next = iohash[idx];
iohash[idx] = ioh;
}
return SCPE_OK;
}
t_stat del_iohandler(void* ctxt)
{
uint32 i;
PNP_INFO* pnp = (PNP_INFO*)ctxt;
if (!pnp) return SCPE_IERR;
for (i=0; i<pnp->io_size; i += pnp->io_incr) {
t_addr p = (pnp->io_base+i) & addrmask;
t_addr idx = MAKEIOHASH(p);
IOHANDLER **ioh = &iohash[idx];
while (*ioh != NULL && (*ioh)->port != p) ioh = &((*ioh)->next);
if (*ioh) {
IOHANDLER *e = *ioh;
*ioh = (*ioh)->next;
free((void*)e);
}
}
return SCPE_OK;
}
/***********************************************************************************************
* Memory handling
* ReadP{B|W|L} and WriteP{B|W|L} simply access physical memory (addrmask applies)
* ReadV{B|W|L} and WriteV{B|W|L} access virtual memory, i.e. after a "decoder" or mmu has processed
* the address/rwmode/fcode
* TranslateAddr is a user-supplied function, to be set into the function pointer,
* which converts an address and other data (e.g. rw, fcode) provided by the CPU
* into the real physical address. This is basically the MMU.
*
* TranslateAddr returns SCPE_OK for valid translation
* SIM_ISIO if I/O dispatch is required; ioh contains pointer to iohandler
* STOP_ERRADDR if address is invalid
* Mem accesses memory, selected by a (translated) address. Override in own code for non-contiguous memory
* Mem returns SCPE_OK and a pointer to the selected byte, if okay, STOP_ERRADR for invalid accesses
*/
/* default handler */
t_stat m68k_translateaddr(t_addr in,t_addr* out, IOHANDLER** ioh,int rw,int fc,int dma)
{
t_addr ma = in & addrmask;
t_addr idx = MAKEIOHASH(ma);
IOHANDLER* i = iohash[idx];
*out = ma;
*ioh = 0;
while (i != NULL && i->port != ma) i = i->next;
if (i) {
*ioh = i;
return SIM_ISIO;
} else
return SCPE_OK;
}
/* default memory pointer */
t_stat m68k_mem(t_addr addr,uint8** mem)
{
if (addr > MEMORYSIZE) return STOP_ERRADR;
*mem = M+addr;
return SCPE_OK;
}
t_stat (*TranslateAddr)(t_addr in,t_addr* out,IOHANDLER** ioh,int rw,int fc,int dma) = &m68k_translateaddr;
t_stat (*Mem)(t_addr addr,uint8** mem) = &m68k_mem;
/* memory access routines
* The Motorola CPU is big endian, whereas others like the i386 is
* little endian. The memory uses the natural order of the emulating CPU.
*
* addressing uses all bits but LSB to access the memory cell
*
* Memorybits 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
* ------68K Byte0-(MSB)-- ---68K Byte1-----------
* ------68K Byte2-------- ---68K Byte3-(LSB)-----
*/
t_stat ReadPB(t_addr a, uint32* val)
{
uint8* mem;
t_stat rc = Mem(a & addrmask,&mem);
switch (rc) {
default:
return rc;
case SIM_NOMEM:
*val = 0xff;
return SCPE_OK;
case SCPE_OK:
*val = *mem & BMASK;
return SCPE_OK;
}
}
t_stat ReadPW(t_addr a, uint32* val)
{
uint8* mem;
uint32 dat1,dat2;
t_stat rc = Mem((a+1)&addrmask,&mem);
switch (rc) {
default:
return rc;
case SIM_NOMEM:
*val = 0xffff;
return SCPE_OK;
case SCPE_OK:
/* 68000/08/10 do not like unaligned access */
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
dat1 = (*(mem-1) & BMASK) << 8;
dat2 = *mem & BMASK;
*val = (dat1 | dat2) & WMASK;
return SCPE_OK;
}
}
t_stat ReadPL(t_addr a, uint32* val)
{
uint8* mem;
uint32 dat1,dat2,dat3,dat4;
t_stat rc = Mem((a+3)&addrmask,&mem);
switch (rc) {
default:
return rc;
case SIM_NOMEM:
*val = 0xffffffff;
return SCPE_OK;
case SCPE_OK:
/* 68000/08/10 do not like unaligned access */
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
dat1 = *(mem-3) & BMASK;
dat2 = *(mem-2) & BMASK;
dat3 = *(mem-1) & BMASK;
dat4 = *mem & BMASK;
*val = (((((dat1 << 8) | dat2) << 8) | dat3) << 8) | dat4;
return SCPE_OK;
}
}
t_stat WritePB(t_addr a, uint32 val)
{
uint8* mem;
t_stat rc = Mem(a&addrmask,&mem);
switch (rc) {
default:
return rc;
case SCPE_OK:
*mem = val & BMASK;
/*fallthru*/
case SIM_NOMEM:
return SCPE_OK;
}
}
t_stat WritePW(t_addr a, uint32 val)
{
uint8* mem;
t_stat rc = Mem((a+1)&addrmask,&mem);
switch (rc) {
default:
return rc;
case SCPE_OK:
/* 68000/08/10 do not like unaligned access */
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
*(mem-1) = (val >> 8) & BMASK;
*mem = val & BMASK;
/*fallthru*/
case SIM_NOMEM:
return SCPE_OK;
}
}
t_stat WritePL(t_addr a, uint32 val)
{
uint8* mem;
t_stat rc = Mem((a+3)&addrmask,&mem);
switch (rc) {
default:
return rc;
case SCPE_OK:
/* 68000/08/10 do not like unaligned access */
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
*(mem-3) = (val >> 24) & BMASK;
*(mem-2) = (val >> 16) & BMASK;
*(mem-1) = (val >> 8) & BMASK;
*mem = val & BMASK;
/*fallthru*/
case SIM_NOMEM:
return SCPE_OK;
}
}
t_stat ReadVB(t_addr a, uint32* val)
{
t_addr addr;
IOHANDLER* ioh;
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
switch (rc) {
case SIM_NOMEM:
/* note this is a hack to persuade memory testing code that there is no memory:
* writing to such an address is a bit bucket,
* and reading from it will return some arbitrary value.
*
* SIM_NOMEM has to be defined for systems without a strict memory handling that will
* result in reading out anything without trapping a memory fault
*/
*val = 0xff;
return SCPE_OK;
case SIM_ISIO:
return ioh->io(ioh,val,IO_READ,BMASK);
case SCPE_OK:
return ReadPB(addr,val);
default:
return rc;
}
}
t_stat ReadVW(t_addr a, uint32* val)
{
t_addr addr;
IOHANDLER* ioh;
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
switch (rc) {
case SIM_NOMEM:
*val = 0xffff;
return SCPE_OK;
case SIM_ISIO:
return ioh->io(ioh,val,IO_READ,WMASK);
case SCPE_OK:
return ReadPW(addr,val);
default:
return rc;
}
}
t_stat ReadVL(t_addr a, uint32* val)
{
t_addr addr;
IOHANDLER* ioh;
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
switch (rc) {
case SIM_NOMEM:
*val = 0xffffffff;
return SCPE_OK;
case SIM_ISIO:
return ioh->io(ioh,val,IO_READ,LMASK);
case SCPE_OK:
return ReadPL(addr,val);
default:
return rc;
}
}
t_stat WriteVB(t_addr a, uint32 val)
{
t_addr addr;
IOHANDLER* ioh;
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
switch (rc) {
case SIM_NOMEM:
/* part 2 of hack for less strict memory handling: ignore anything written
* to a nonexisting address
*/
return SCPE_OK;
case SIM_ISIO:
return ioh->io(ioh,&val,IO_WRITE,BMASK);
case SCPE_OK:
return WritePB(addr,val);
default:
return rc;
}
}
t_stat WriteVW(t_addr a, uint32 val)
{
t_addr addr;
IOHANDLER* ioh;
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
switch (rc) {
case SIM_NOMEM:
return SCPE_OK;
case SIM_ISIO:
return ioh->io(ioh,&val,IO_WRITE,WMASK);
case SCPE_OK:
return WritePW(addr,val);
default:
return rc;
}
}
t_stat WriteVL(t_addr a, uint32 val)
{
t_addr addr;
IOHANDLER* ioh;
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
switch (rc) {
case SIM_NOMEM:
return SCPE_OK;
case SIM_ISIO:
return ioh->io(ioh,&val,IO_WRITE,LMASK);
case SCPE_OK:
return WritePL(addr,val);
default:
return rc;
}
}

3786
SAGE/m68k_parse.tab.c Normal file

File diff suppressed because it is too large Load diff

360
SAGE/m68k_parse.tab.h Normal file
View file

@ -0,0 +1,360 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
A0 = 258,
A1 = 259,
A2 = 260,
A3 = 261,
A4 = 262,
A5 = 263,
A6 = 264,
A7 = 265,
D0 = 266,
D1 = 267,
D2 = 268,
D3 = 269,
D4 = 270,
D5 = 271,
D6 = 272,
D7 = 273,
CCR = 274,
SR = 275,
USP = 276,
PC = 277,
NUMBER = 278,
ABCD = 279,
ADD = 280,
ADDA = 281,
ADDI = 282,
ADDQ = 283,
ADDX = 284,
AND = 285,
ANDI = 286,
OR = 287,
ORI = 288,
SBCD = 289,
SUB = 290,
SUBA = 291,
SUBI = 292,
SUBQ = 293,
SUBX = 294,
ASL = 295,
ASR = 296,
LSL = 297,
LSR = 298,
ROL = 299,
ROR = 300,
ROXL = 301,
ROXR = 302,
BCC = 303,
BCS = 304,
BEQ = 305,
BGE = 306,
BGT = 307,
BHI = 308,
BLE = 309,
BLS = 310,
BLT = 311,
BMI = 312,
BNE = 313,
BPL = 314,
BVC = 315,
BVS = 316,
BSR = 317,
BRA = 318,
BCLR = 319,
BSET = 320,
BCHG = 321,
BTST = 322,
CHK = 323,
CMP = 324,
CMPA = 325,
CMPI = 326,
CMPM = 327,
EOR = 328,
EORI = 329,
EXG = 330,
EXT = 331,
DIVU = 332,
DIVS = 333,
MULU = 334,
MULS = 335,
DBCC = 336,
DBCS = 337,
DBEQ = 338,
DBF = 339,
DBGE = 340,
DBGT = 341,
DBHI = 342,
DBLE = 343,
DBLS = 344,
DBLT = 345,
DBMI = 346,
DBNE = 347,
DBPL = 348,
DBT = 349,
DBVC = 350,
DBVS = 351,
SCC = 352,
SCS = 353,
SEQ = 354,
SF = 355,
SGE = 356,
SGT = 357,
SHI = 358,
SLE = 359,
SLS = 360,
SLT = 361,
SMI = 362,
SNE = 363,
SPL = 364,
ST = 365,
SVC = 366,
SVS = 367,
ILLEGAL = 368,
NOP = 369,
RESET = 370,
RTE = 371,
RTR = 372,
RTS = 373,
TRAPV = 374,
JMP = 375,
JSR = 376,
LEA = 377,
LINK = 378,
MOVE = 379,
MOVEA = 380,
MOVEM = 381,
MOVEP = 382,
MOVEQ = 383,
CLR = 384,
NEG = 385,
NEGX = 386,
NBCD = 387,
NOT = 388,
PEA = 389,
STOP = 390,
TAS = 391,
SWAP = 392,
TRAP = 393,
TST = 394,
UNLK = 395,
PREDEC = 396,
POSTINC = 397,
BSIZE = 398,
WSIZE = 399,
LSIZE = 400,
SSIZE = 401
};
#endif
/* Tokens. */
#define A0 258
#define A1 259
#define A2 260
#define A3 261
#define A4 262
#define A5 263
#define A6 264
#define A7 265
#define D0 266
#define D1 267
#define D2 268
#define D3 269
#define D4 270
#define D5 271
#define D6 272
#define D7 273
#define CCR 274
#define SR 275
#define USP 276
#define PC 277
#define NUMBER 278
#define ABCD 279
#define ADD 280
#define ADDA 281
#define ADDI 282
#define ADDQ 283
#define ADDX 284
#define AND 285
#define ANDI 286
#define OR 287
#define ORI 288
#define SBCD 289
#define SUB 290
#define SUBA 291
#define SUBI 292
#define SUBQ 293
#define SUBX 294
#define ASL 295
#define ASR 296
#define LSL 297
#define LSR 298
#define ROL 299
#define ROR 300
#define ROXL 301
#define ROXR 302
#define BCC 303
#define BCS 304
#define BEQ 305
#define BGE 306
#define BGT 307
#define BHI 308
#define BLE 309
#define BLS 310
#define BLT 311
#define BMI 312
#define BNE 313
#define BPL 314
#define BVC 315
#define BVS 316
#define BSR 317
#define BRA 318
#define BCLR 319
#define BSET 320
#define BCHG 321
#define BTST 322
#define CHK 323
#define CMP 324
#define CMPA 325
#define CMPI 326
#define CMPM 327
#define EOR 328
#define EORI 329
#define EXG 330
#define EXT 331
#define DIVU 332
#define DIVS 333
#define MULU 334
#define MULS 335
#define DBCC 336
#define DBCS 337
#define DBEQ 338
#define DBF 339
#define DBGE 340
#define DBGT 341
#define DBHI 342
#define DBLE 343
#define DBLS 344
#define DBLT 345
#define DBMI 346
#define DBNE 347
#define DBPL 348
#define DBT 349
#define DBVC 350
#define DBVS 351
#define SCC 352
#define SCS 353
#define SEQ 354
#define SF 355
#define SGE 356
#define SGT 357
#define SHI 358
#define SLE 359
#define SLS 360
#define SLT 361
#define SMI 362
#define SNE 363
#define SPL 364
#define ST 365
#define SVC 366
#define SVS 367
#define ILLEGAL 368
#define NOP 369
#define RESET 370
#define RTE 371
#define RTR 372
#define RTS 373
#define TRAPV 374
#define JMP 375
#define JSR 376
#define LEA 377
#define LINK 378
#define MOVE 379
#define MOVEA 380
#define MOVEM 381
#define MOVEP 382
#define MOVEQ 383
#define CLR 384
#define NEG 385
#define NEGX 386
#define NBCD 387
#define NOT 388
#define PEA 389
#define STOP 390
#define TAS 391
#define SWAP 392
#define TRAP 393
#define TST 394
#define UNLK 395
#define PREDEC 396
#define POSTINC 397
#define BSIZE 398
#define WSIZE 399
#define LSIZE 400
#define SSIZE 401
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 74 "m68k_parse.y"
{
int rc;
int reg;
int wl;
int opc;
struct _ea ea;
t_value num;
struct _rea rea;
struct _mask mask;
struct _brop brop;
}
/* Line 1489 of yacc.c. */
#line 353 "m68k_parse.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;

667
SAGE/m68k_parse.y.txt Normal file
View file

@ -0,0 +1,667 @@
%{
/* m68k_parse.c: line assembler for generic m68k_cpu
Copyright (c) 2009-2010, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#include "m68k_cpu.h"
#include <ctype.h>
#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#endif
struct _ea {
int ea;
int cnt;
t_value arg[10];
};
struct _rea {
int reg;
struct _ea ea;
};
struct _mask {
int x;
int d;
};
struct _brop {
int opc;
int len;
};
static int oplen;
static int movemx[] = { 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080 };
static int movemd[] = { 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001,
0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100 };
static int yyrc;
static int yyerrc;
extern int yylex();
static int _genop(t_value arg);
static int _genea(struct _ea arg);
static int _genbr(t_value arg,t_value,int);
static void yyerror(char* s);
#define YYDEBUG 1
%}
%union {
int rc;
int reg;
int wl;
int opc;
struct _ea ea;
t_value num;
struct _rea rea;
struct _mask mask;
struct _brop brop;
}
%token A0 A1 A2 A3 A4 A5 A6 A7 D0 D1 D2 D3 D4 D5 D6 D7
%token CCR SR USP PC
%token <num> NUMBER
%token ABCD ADD ADDA ADDI ADDQ ADDX AND ANDI OR ORI SBCD SUB SUBA SUBI SUBQ SUBX
%token ASL ASR LSL LSR ROL ROR ROXL ROXR
%token BCC BCS BEQ BGE BGT BHI BLE BLS BLT BMI BNE BPL BVC BVS BSR BRA
%token BCLR BSET BCHG BTST CHK CMP CMPA CMPI CMPM EOR EORI EXG EXT
%token DIVU DIVS MULU MULS
%token DBCC DBCS DBEQ DBF DBGE DBGT DBHI DBLE DBLS DBLT DBMI DBNE DBPL DBT DBVC DBVS
%token SCC SCS SEQ SF SGE SGT SHI SLE SLS SLT SMI SNE SPL ST SVC SVS
%token ILLEGAL NOP RESET RTE RTR RTS TRAPV
%token JMP JSR LEA LINK MOVE MOVEA MOVEM MOVEP MOVEQ
%token CLR NEG NEGX NBCD NOT PEA STOP TAS SWAP TRAP TST UNLK
%token PREDEC POSTINC BSIZE WSIZE LSIZE SSIZE
%start stmt
%type <opc> bcdop bcdarg dualop immop qop immop2 shftarg monop btop
%type <opc> mdop dbop jop arop
%type <opc> direct
%type <brop> brop
%type <rea> dualarg shftop
%type <reg> dreg areg
%type <ea> ea0 ea1 ea2 ea3 ea4 ea5 ea6 ea70 ea72 ea73 ea74 eama eaa eaall eada eadas easr ead eac eacad eacai
%type <wl> szwl szbwl szmv szm szs
%type <mask> regs reglist
%%
stmt:
bcdop bcdarg { _genop($1 | $2); yyrc = -1; }
| dualop dualarg { _genop($1 | $2.reg | $2.ea.ea); yyrc = _genea($2.ea) -1; }
| immop '#' NUMBER ',' eada { _genop($1 | $5.ea); if (oplen==0) { _genop($3 & 0xff); yyrc = _genea($5) - 3; }
else if (oplen==1) { _genop($3); yyrc = _genea($5) - 3; } else { _genop($3>>16); _genop($3 & 0xffff); yyrc = _genea($5)-5; } }
| qop '#' NUMBER ',' eaa { _genop($1 | (($3&7)<<9) | $5.ea); yyrc = _genea($5) - 1; }
| immop2 '#' NUMBER ',' eadas { _genop($1 | $5.ea); if (oplen==0) { _genop($3 & 0xff); yyrc = _genea($5) - 3; }
else if (oplen==1) { _genop($3); yyrc = _genea($5) - 3; } else { _genop($3>>16); _genop($3 & 0xffff); yyrc = _genea($5)-5; } }
| shftop { _genop($1.reg); if (($1.reg&0xc0)==0xc0) yyrc = _genea($1.ea) - 1; else { yyrc = -1; } }
| brop NUMBER { yyrc = _genbr($1.opc,$2,$1.len) - 1; }
| btop dreg ',' eada { _genop($1 | ($2<<9) | 0x100 | $4.ea); yyrc = _genea($4) - 1; }
| btop '#' NUMBER ',' eada { _genop($1 | 0x0800 | $5.ea); _genop($3); yyrc = _genea($5) - 3; }
| CHK ead ',' dreg { _genop(0x4180 | ($4<<9) | $2.ea); yyrc = _genea($2) - 1; }
| monop eada { _genop($1 | $2.ea); yyrc = _genea($2) - 1; }
| CMP szbwl eaall ',' dreg { _genop(0xb000 | ($2<<6) | ($5<<9) | $3.ea); yyrc = _genea($3) - 1; }
| mdop ead ',' dreg { _genop($1 | ($4<<9) | $2.ea); yyrc = _genea($2) - 1; }
| CMPA szwl eaall ',' areg { _genop(0xb0c0 | ($2<<8) | ($5<<9) | $3.ea); yyrc = _genea($3) - 1; }
| CMPM szbwl ea3 ',' ea3 { _genop(0xb108 | ($5.ea<<9) | ($2<<6) | $3.ea); yyrc = -1; }
| dbop dreg ',' NUMBER { yyrc = _genbr($1 | $2, $4, 1) - 1; }
| EOR szbwl dreg ',' eada { _genop(0xb000 | ($2 << 6) | 0x100 | $5.ea); yyrc = _genea($5) - 1; }
| EXG dreg ',' dreg { _genop(0xc140 | ($2<<9) | $4); yyrc = -1; }
| EXG areg ',' areg { _genop(0xc148 | ($2<<9) | $4); yyrc = -1; }
| EXG areg ',' dreg { _genop(0xc188 | ($4<<9) | $2); yyrc = -1; }
| EXG dreg ',' areg { _genop(0xc188 | ($2<<9) | $4); yyrc = -1; }
| EXT szwl dreg { _genop(0x4840 | ($2<<6) | $3); yyrc = -1; }
| direct { _genop($1); yyrc = -1; }
| jop eac { _genop($1 | $2.ea); yyrc = _genea($2) -1; }
| LEA eac ',' areg { _genop(0x41c0 | $2.ea); yyrc = _genea($2) - 1; }
| LINK areg ',' '#' NUMBER { _genop(0x4e50 | $2); _genop($5); yyrc = -3; }
| MOVE szmv eaall ',' eadas { if ($5.ea==074) { _genop(0x44c0 | ($5.cnt==1?0x0200:0x0000) | $3.ea); yyrc = _genea($3) - 1; }
else { int tmp = (($5.ea&070)>>3)|(($5.ea&7)<<3); _genop(0x0000 | ($2<<12) | (tmp<<6) | $3.ea);
yyrc = _genea($3) - 1; yyrc += _genea($5); } }
| MOVE SR ',' eada { _genop(0x40c0 | $4.ea); yyrc = _genea($4) - 1; }
| MOVE USP ',' areg { _genop(0x4e68 | $4); yyrc = -1; }
| MOVE areg ',' USP { _genop(0x4e60 | $2); yyrc = -1; }
| MOVEA szm eada ',' areg { _genop(0x0040 | ($2<<12) | ($5<<9) | $3.ea); yyrc = _genea($3) - 1; }
| MOVEM szwl reglist ',' eacad { _genop(0x4880 | ($2<<6) | $5.ea); _genop(($5.ea&070)==040 ? $3.d : $3.x); yyrc = _genea($5) - 3; }
| MOVEM szwl eacai ',' reglist { _genop(0x4c80 | ($2<<6) | $3.ea); _genop($5.x); yyrc = _genea($3) - 3; }
| MOVEP szwl dreg ',' ea5 { _genop(0x0108 | ($3<<9) | ($2<<6) | ($5.ea & 7)); yyrc = _genea($5) - 1; }
| MOVEP szwl ea5 ',' dreg { _genop(0x0188 | ($5<<9) | ($2<<6) | ($3.ea & 7)); yyrc = _genea($3) - 1; }
| MOVEQ '#' NUMBER ',' dreg { _genop(0x7000 | ($5<<9) | ($3&0xff)); yyrc = -1; }
| STOP '#' NUMBER { _genop(0x4e72); yyrc = _genop($3&0xffff) - 1; }
| arop szwl eaall ',' areg { _genop($1 | ($5<<9) | ($2<<8) | $3.ea); yyrc = _genea($3) - 1; }
| SWAP dreg { _genop(0x4840 | $2); yyrc = -1; }
| TRAP '#' NUMBER { _genop(0x4e40 | ($3 & 0x0f)); yyrc = -1; }
| UNLK areg { _genop(0x4e58 | $2); yyrc = -1; }
;
arop:
ADDA { $$ = 0xd0c0; }
| SUBA { $$ = 0x90c0; };
bcdop:
ABCD { $$ = 0xc100; }
| ADDX szbwl { $$ = 0xd100 | ($2<<6); }
| SBCD { $$ = 0x8100; }
| SUBX szbwl { $$ = 0x9100 | ($2<<6); }
;
dualop:
ADD szbwl { $$ = 0xd000 | ($2<<6); }
| AND szbwl { $$ = 0xc000 | ($2<<6); }
| OR szbwl { $$ = 0x8000 | ($2<<6); }
| SUB szbwl { $$ = 0x9000 | ($2<<6); }
;
immop:
ADDI szbwl { $$ = 0x0600 | ($2<<6); }
| CMPI szbwl { $$ = 0x0c00 | ($2<<6); }
| SUBI szbwl { $$ = 0x0400 | ($2<<6); }
;
immop2:
ANDI szbwl { $$ = 0x0200 | ($2<<6); }
| EORI szbwl { $$ = 0x0a00 | ($2<<6); }
| ORI szbwl { $$ = 0x0000 | ($2<<6); }
;
qop:
ADDQ szbwl { $$ = 0x5000 | ($2<<6); }
| SUBQ szbwl { $$ = 0x5100 | ($2<<6); }
;
shftop:
ASL eama { $$.reg = 0xe1c0 | $2.ea; $$.ea = $2; }
| ASL szbwl shftarg { $$.reg = 0xe100 | ($2<<6) | $3; }
| ASR eama { $$.reg = 0xe0c0 | $2.ea; $$.ea = $2; }
| ASR szbwl shftarg { $$.reg = 0xe000 | ($2<<6) | $3; }
| LSL eama { $$.reg = 0xe3c0 | $2.ea; $$.ea = $2; }
| LSL szbwl shftarg { $$.reg = 0xe108 | ($2<<6) | $3; }
| LSR eama { $$.reg = 0xe2c0 | $2.ea; $$.ea = $2; }
| LSR szbwl shftarg { $$.reg = 0xe008 | ($2<<6) | $3; }
| ROL eama { $$.reg = 0xe7c0 | $2.ea; $$.ea = $2; }
| ROL szbwl shftarg { $$.reg = 0xe118 | ($2<<6) | $3; }
| ROR eama { $$.reg = 0xe6c0 | $2.ea; $$.ea = $2; }
| ROR szbwl shftarg { $$.reg = 0xe018 | ($2<<6) | $3; }
| ROXL eama { $$.reg = 0xe5c0 | $2.ea; $$.ea = $2; }
| ROXL szbwl shftarg { $$.reg = 0xe100 | ($2<<6) | $3; }
| ROXR eama { $$.reg = 0xe4c0 | $2.ea; $$.ea = $2; }
| ROXR szbwl shftarg { $$.reg = 0xe000 | ($2<<6) | $3; }
;
brop:
BCC { $$.opc = 0x6400; $$.len = 1; }
| BCS { $$.opc = 0x6500; $$.len = 1; }
| BEQ { $$.opc = 0x6700; $$.len = 1; }
| BGE { $$.opc = 0x6c00; $$.len = 1; }
| BGT { $$.opc = 0x6e00; $$.len = 1; }
| BHI { $$.opc = 0x6200; $$.len = 1; }
| BLE { $$.opc = 0x6f00; $$.len = 1; }
| BLS { $$.opc = 0x6300; $$.len = 1; }
| BLT { $$.opc = 0x6d00; $$.len = 1; }
| BMI { $$.opc = 0x6b00; $$.len = 1; }
| BNE { $$.opc = 0x6600; $$.len = 1; }
| BPL { $$.opc = 0x6a00; $$.len = 1; }
| BVC { $$.opc = 0x6800; $$.len = 1; }
| BVS { $$.opc = 0x6900; $$.len = 1; }
| BSR { $$.opc = 0x6100; $$.len = 1; }
| BRA { $$.opc = 0x6000; $$.len = 1; }
| BCC szs { $$.opc = 0x6400; $$.len = 0; }
| BCS szs { $$.opc = 0x6500; $$.len = 0; }
| BEQ szs { $$.opc = 0x6700; $$.len = 0; }
| BGE szs { $$.opc = 0x6c00; $$.len = 0; }
| BGT szs { $$.opc = 0x6e00; $$.len = 0; }
| BHI szs { $$.opc = 0x6200; $$.len = 0; }
| BLE szs { $$.opc = 0x6f00; $$.len = 0; }
| BLS szs { $$.opc = 0x6300; $$.len = 0; }
| BLT szs { $$.opc = 0x6d00; $$.len = 0; }
| BMI szs { $$.opc = 0x6b00; $$.len = 0; }
| BNE szs { $$.opc = 0x6600; $$.len = 0; }
| BPL szs { $$.opc = 0x6a00; $$.len = 0; }
| BVC szs { $$.opc = 0x6800; $$.len = 0; }
| BVS szs { $$.opc = 0x6900; $$.len = 0; }
| BSR szs { $$.opc = 0x6100; $$.len = 0; }
| BRA szs { $$.opc = 0x6000; $$.len = 0; }
;
btop:
BCHG { $$ = 0x0040; }
| BCLR { $$ = 0x0080; }
| BSET { $$ = 0x00c0; }
| BTST { $$ = 0x0000; }
;
monop:
CLR szbwl { $$ = 0x4200 | ($2<<6); }
| NBCD { $$ = 0x4800; }
| NEG szbwl { $$ = 0x4400 | ($2<<6); }
| NEGX szbwl { $$ = 0x4000 | ($2<<6); }
| NOT szbwl { $$ = 0x4600 | ($2<<6); }
| SCC { $$ = 0x54c0; }
| SCS { $$ = 0x55c0; }
| SEQ { $$ = 0x57c0; }
| SF { $$ = 0x51c0; }
| SGE { $$ = 0x5cc0; }
| SGT { $$ = 0x5ec0; }
| SHI { $$ = 0x52c0; }
| SLE { $$ = 0x5fc0; }
| SLS { $$ = 0x53c0; }
| SLT { $$ = 0x5dc0; }
| SMI { $$ = 0x5bc0; }
| SNE { $$ = 0x56c0; }
| SPL { $$ = 0x5ac0; }
| ST { $$ = 0x50c0; }
| SVC { $$ = 0x58c0; }
| SVS { $$ = 0x59c0; }
| TAS { $$ = 0x4ac0; }
| TST szbwl { $$ = 0x4a00 | ($2<<6); }
;
mdop:
DIVS { $$ = 0x81c0; }
| DIVU { $$ = 0x80c0; }
| MULS { $$ = 0xc1c0; }
| MULU { $$ = 0xc0c0; }
;
dbop:
DBCC { $$ = 0x54c8; }
| DBCS { $$ = 0x55c8; }
| DBEQ { $$ = 0x57c8; }
| DBGE { $$ = 0x5cc8; }
| DBGT { $$ = 0x5ec8; }
| DBHI { $$ = 0x52c8; }
| DBLE { $$ = 0x5fc8; }
| DBLS { $$ = 0x53c8; }
| DBLT { $$ = 0x5dc8; }
| DBMI { $$ = 0x5bc8; }
| DBNE { $$ = 0x56c8; }
| DBPL { $$ = 0x5ac8; }
| DBVC { $$ = 0x58c8; }
| DBVS { $$ = 0x59c8; }
| DBF { $$ = 0x51c8; }
| DBT { $$ = 0x50c8; }
;
direct:
ILLEGAL { $$ = 0x4afc; }
| NOP { $$ = 0x4e71; }
| RESET { $$ = 0x4e70; }
| RTE { $$ = 0x4e73; }
| RTR { $$ = 0x4e77; }
| RTS { $$ = 0x4e75; }
| TRAPV { $$ = 0x4e76; }
;
jop:
JMP { $$ = 0x4ec0; }
| JSR { $$ = 0x4e80; }
| PEA { $$ = 0x4840; };
shftarg:
dreg ',' dreg { $$ = ($1<<9) | 0x20 | $3; }
| '#' NUMBER ',' dreg { $$ = (($2 & 7)<<9) | $4; };
bcdarg:
ea0 ',' ea0 { $$ = (($1.ea & 7) << 9) | ($3.ea & 7); }
| ea4 ',' ea4 { $$ = (($1.ea & 7) << 9) | 0x0008 | ($3.ea & 7); };
dualarg:
dreg ',' eaa { if (($3.ea & 070)==0) { /* dx,dy must be swapped */
$$.reg = ($3.ea & 7)<<9; $3.ea = $1 & 7; $$.ea = $3; }
else { $$.reg = ($1<<9) | 0x100; $$.ea = $3; } }
| eama ',' dreg { $$.reg = ($3<<9); $$.ea = $1; };
areg:
A0 { $$=0; }
| A1 { $$=1; }
| A2 { $$=2; }
| A3 { $$=3; }
| A4 { $$=4; }
| A5 { $$=5; }
| A6 { $$=6; }
| A7 { $$=7; };
dreg:
D0 { $$=0; }
| D1 { $$=1; }
| D2 { $$=2; }
| D3 { $$=3; }
| D4 { $$=4; }
| D5 { $$=5; }
| D6 { $$=6; }
| D7 { $$=7; };
szs:
SSIZE { $$ = 1; oplen = 0; }
szwl:
WSIZE { $$ = 0; oplen = 1; }
| LSIZE { $$ = 1; oplen = 2; };
szbwl:
BSIZE { $$ = 0; oplen = 0; }
| WSIZE { $$ = 1; oplen = 1; }
| LSIZE { $$ = 2; oplen = 2; };
szmv:
BSIZE { $$ = 1; oplen = 0; }
| WSIZE { $$ = 3; oplen = 1; }
| LSIZE { $$ = 2; oplen = 2; };
szm:
WSIZE { $$ = 3; oplen = 1; }
| LSIZE { $$ = 2; oplen = 2; };
reglist:
regs { $$ = $1; }
| regs '/' reglist { $$.x = $1.x | $3.x; $$.d = $1.d | $3.d; };
regs:
areg { $$.x = movemx[$1]; $$.d = movemd[$1]; }
| dreg { $$.x = movemx[$1+8]; $$.d = movemd[$1+8]; }
| areg '-' areg { int i,l=$1,h=$3; if (l>h) { l=$3; h=$1; } $$.x = $$.d = 0;
for (i=l; i<=h; i++) { $$.d |= movemx[i]; $$.d |= movemd[i]; } }
| dreg '-' dreg { int i,l=$1,h=$3; if (l>h) { l=$3; h=$1; } $$.x = $$.d = 0;
for (i=l; i<=h; i++) { $$.x |= movemx[i+8]; $$.d |= movemd[i+8]; } }
;
eama: ea1 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70 | ea72 | ea73 | ea74;
eaa: ea0 | ea1 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70;
ead: ea0 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70 | ea72 | ea73 | ea74;
eaall: ea0 | eama;
eada: ea0 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70;
eadas: eada | easr;
eac: ea2 | ea5 | ea6 | ea70 | ea72 | ea73;
eacai: ea2 | ea3 | ea5 | ea6 | ea70;
eacad: ea2 | ea4 | ea5 | ea6 | ea70;
ea0:
dreg { $$.ea = $1; $$.cnt = 0; };
ea1:
areg { $$.ea = 010 | $1; $$.cnt = 0; };
ea2:
'(' areg ')' { $$.ea = 020 | $2; $$.cnt = 0; };
ea3:
'(' areg POSTINC { $$.ea = 030 | $2; $$.cnt = 0; };
ea4:
PREDEC areg ')' { $$.ea = 040 | $2; $$.cnt = 0; };
ea5:
'(' NUMBER ',' areg ')' { $$.ea = 050 | $4; $$.cnt = 1; $$.arg[0] = $2; };
ea6:
'(' NUMBER ',' areg ',' dreg szwl ')'
{ $$.ea = 060 | $4; $$.cnt = 1; $$.arg[0] = 0x8000 | ($6<<12) | ($7<<11) | ($2 & 0xff); }
| '(' NUMBER ',' areg ',' areg szwl ')'
{ $$.ea = 060 | $4; $$.cnt = 1; $$.arg[0] = ($6<<12) | ($7<<11) | ($2 & 0xff); };
ea70:
'(' NUMBER ')' szwl { if ($4==0) { $$.ea = 070; $$.cnt = 1; $$.arg[0] = $2; }
else { $$.ea = 071; $$.cnt = 2; $$.arg[0] = $2 >> 16; $$.arg[1] = $2 & 0xffff; } }
| '(' NUMBER ')' { int tmp = ($2>>15) & 0x1ffff; if (tmp==0 || tmp==0x1ffff) { $$.ea = 070; $$.cnt = 1; $$.arg[0] = $2; }
else { $$.ea = 070; $$.cnt = 2; $$.arg[0] = $2 >> 16; $$.arg[1] = $2 & 0xffff; } };
ea72:
'(' NUMBER ',' PC ')' { $$.ea = 072; $$.cnt = 1; $$.arg[0] = $2; }
| NUMBER { $$.ea = 072; $$.cnt = 1; $$.arg[0] = $1; };
ea73:
'(' NUMBER ',' PC ',' dreg szwl ')'
{ $$.ea = 073; $$.cnt = 1; $$.arg[0] = 0x8000 | ($6<<12) | ($7<<11) | ($2 & 0xff); }
| '(' NUMBER ',' PC ',' areg szwl ')'
{ $$.ea = 073; $$.cnt = 1; $$.arg[0] = ($6<<12) | ($7<<11) | ($2 & 0xff); };
ea74:
'#' NUMBER { $$.ea = 074; if (oplen==0) { $$.cnt = 1; $$.arg[0] = $2 & 0xff; }
else if (oplen==1) { $$.cnt = 1; $$.arg[0] = $2 & 0xffff; }
else { $$.cnt = 2; $$.arg[0] = $2 >> 16; $$.arg[1] = $2 & 0xffff; } };
easr:
CCR { $$.ea = 074; $$.cnt = 0; }
| SR { $$.ea = 074; $$.cnt = 1; };
%%
static void yyerror(char* s)
{
/* do not emit anything, but set error flag */
yyerrc = 1;
}
struct _optable {
char* mnem;
int token;
};
static struct _optable ops[] = {
{ "abcd", ABCD }, { "add", ADD }, { "adda", ADDA }, { "addi", ADDI },
{ "addq", ADDQ }, { "addx", ADDX }, { "and", AND }, { "andi", ANDI },
{ "asl", ASL }, { "asr", ASR }, { "bcc", BCC }, { "bcs", BCS },
{ "beq", BEQ }, { "bge", BGE }, { "bgt", BGT }, { "bhi", BHI },
{ "ble", BLE }, { "bls", BLS }, { "blt", BLT }, { "bmi", BMI },
{ "bne", BNE }, { "bpl", BPL }, { "bvc", BVC }, { "bvs", BVS },
{ "bchg", BCHG }, { "bclr", BCLR }, { "bra", BRA }, { "bset", BSET },
{ "bsr", BSR }, { "btst", BTST }, { "chk", CHK }, { "clr", CLR },
{ "cmp", CMP }, { "cmpa", CMPA }, { "cmpi", CMPI }, { "cmpm", CMPM },
{ "dbcc", DBCC }, { "dbcs", DBCS }, { "dbeq", DBEQ }, { "dbf", DBF },
{ "dbge", DBGE }, { "dbgt", DBGT }, { "dbhi", DBHI }, { "dble", DBLE },
{ "dbls", DBLS }, { "dblt", DBLT }, { "dbmi", DBMI }, { "dbne", DBNE },
{ "dbpl", DBPL }, { "dbt", DBT }, { "dbvc", DBVC }, { "dbvs", DBVS },
{ "divs", DIVS }, { "divu", DIVU }, { "eor", EOR }, { "eori", EORI },
{ "exg", EXG }, { "ext", EXT }, { "illegal",ILLEGAL }, { "jmp", JMP },
{ "jsr", JSR }, { "lea", LEA }, { "link", LINK }, { "lsl", LSL },
{ "lsr", LSR }, { "move", MOVE }, { "movea", MOVEA }, { "movem", MOVEM },
{ "movep", MOVEP }, { "moveq", MOVEQ }, { "muls", MULS }, { "mulu", MULU },
{ "nbcd", NBCD }, { "neg", NEG }, { "negx", NEGX }, { "nop", NOP },
{ "not", NOT }, { "or", OR }, { "ori", ORI }, { "pea", PEA },
{ "reset", RESET }, { "rol", ROL }, { "ror", ROR }, { "roxl", ROXL },
{ "roxr", ROXR }, { "rte", RTE }, { "rtr", RTR },
{ "rts", RTS }, { "scc", SCC }, { "scs", SCS }, { "seq", SEQ },
{ "sf", SF }, { "sge", SGE }, { "sgt", SGT }, { "shi", SHI },
{ "sle", SLE }, { "sls", SLS }, { "slt", SLT }, { "smi", SMI },
{ "sne", SNE }, { "spl", SPL }, { "st", ST }, { "svc", SVC },
{ "svs", SVS }, { "stop", STOP }, { "sub", SUB }, { "suba", SUBA },
{ "subi", SUBI }, { "subq", SUBQ }, { "subx", SUBX }, { "swap", SWAP },
{ "tas", TAS }, { "trap", TRAP }, { "trapv", TRAPV }, { "tst", TST },
{ "unlk", UNLK }, { "a0", A0 }, { "a1", A1 }, { "a2", A2 },
{ "a3", A3 }, { "a4", A4 }, { "a5", A5 }, { "a6", A6 },
{ "a7", A7 }, { "d0", D0 }, { "d1", D1 }, { "d2", D2 },
{ "d3", D3 }, { "d4", D4 }, { "d5", D5 }, { "d6", D6 },
{ "d7", D7 }, { "ccr", CCR }, { "sr", SR }, { "usp", USP },
{ "pc", PC },
{ 0, 0 }
};
typedef struct _ophash {
struct _ophash* next;
struct _optable* op;
} OPHASH;
#define OPHASHSIZE 97
static OPHASH **ophash = 0;
static int getophash(const char* s)
{
int h = 0;
while (*s++) h += (int)*s;
return h % OPHASHSIZE;
}
static int oplookup(const char* s)
{
int idx = getophash(s);
OPHASH* oph = ophash[idx];
if (oph) {
if (oph->next) {
while (oph) {
if (!strcmp(s,oph->op->mnem)) return oph->op->token;
oph = oph->next;
}
return 0;
}
return oph->op->token;
}
return 0;
}
static void init_ophash()
{
struct _optable* op = ops;
OPHASH* oph;
ophash = (OPHASH**)calloc(sizeof(OPHASH*),OPHASHSIZE);
while (op->mnem) {
int idx = getophash(op->mnem);
oph = (OPHASH*)malloc(sizeof(OPHASH));
oph->next = ophash[idx];
oph->op = op;
ophash[idx] = oph;
op++;
}
}
static char* yystream;
int yylex()
{
char ident[30];
char *p = ident;
char c = yystream[0];
while (c != 0 && (c=='\t' || c==' ')) {
c = *++yystream;
}
if (c==0) return EOF;
if (isalpha(c)) {
while (isalnum(c) && (p-ident)<28) {
*p++ = tolower(c); c = *++yystream;
}
*p = 0;
if (p>ident) { return oplookup(ident); }
return EOF;
} else if (isdigit(c)) {
*p++ = c;
if (yystream[1]=='x' || yystream[1]=='X') { *p++ = 'x'; yystream++; }
c = *++yystream;
while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) {
*p++ = c; c = *++yystream;
}
*p = 0;
yylval.num = strtol(ident,0,0);
return NUMBER;
} else if (c=='$') {
if (isdigit(yystream[1]) || isxdigit(yystream[1])) {
c = *++yystream;
while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) {
*p++ = c; c = *++yystream;
}
*p = 0;
yylval.num = strtol(ident,0,16);
return NUMBER;
} else return '$';
} else if (c == '-' && yystream[1] == '(') {
yystream += 2; return PREDEC;
} else if (c == ')' && yystream[1] == '+') {
yystream += 2; return POSTINC;
} else if (c == '.') {
switch (yystream[1]) {
case 'b': yystream += 2; return BSIZE;
case 'w': yystream += 2; return WSIZE;
case 'l': yystream += 2; return LSIZE;
case 's': yystream += 2; return SSIZE;
default: yystream++; return '.';
}
} else {
++yystream; return c;
}
}
static t_value *yyvalptr;
static t_addr yyaddr;
t_stat parse_sym(char* c, t_addr a, UNIT* u, t_value* val, int32 sw)
{
char ch;
if (!ophash) init_ophash();
yyvalptr = val;
yyaddr = a;
yystream = c;
yyerrc = 0;
ch = *yystream;
while (ch != 0 && (ch=='\t' || ch==' ')) {
ch = *++yystream;
}
if (ch == 0) return 0;
if (sw & SWMASK('Y')) yydebug = 1 - yydebug;
if ((sw & SWMASK('A')) || ch=='\'') {
if ((ch = yystream[1])) {
val[0] = (uint32)ch;
return SCPE_OK;
} else return SCPE_ARG;
}
if ((sw & SWMASK('C')) || ch=='"') {
if ((ch = yystream[1])) {
val[0] = ((uint32)ch << 8) | (uint32)yystream[1];
return SCPE_OK;
} else return SCPE_ARG;
}
yyparse();
printf("rc=%d\n",yyrc);
if (yyerrc) return SCPE_ARG;
return yyrc;
}
static int _genop(t_value arg)
{
// printf("_genop(%x)@%x\n",arg,(int)yyvalptr);
*yyvalptr = arg;
yyvalptr++;
return -1;
}
static int _genea(struct _ea arg)
{
int i;
for (i=0; i<arg.cnt; i++) _genop(arg.arg[i]);
return -(arg.cnt*2)-1;
}
static int _genbr(t_value arg,t_addr tgt,int len)
{
t_addr a = tgt - yyaddr -2;
if (len==1) {
_genop(arg);
_genop(a & 0xffff);
a &= 0xffff8000;
if (a != 0x00000000 && a != 0xffff8000) return SCPE_ARG;
return -3;
} else {
_genop(arg | (a&0xff));
a &= 0xffffff80;
if (a != 0x00000000 && a != 0xffffff80) return SCPE_ARG;
return -1;
}
}

307
SAGE/m68k_scp.c Normal file
View file

@ -0,0 +1,307 @@
/* m68k_scp.c: 68k simulator SCP extension
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
17-Jul-10 HV Initial version
*/
#include "sim_defs.h"
#include "m68k_cpu.h"
#include <ctype.h>
static t_bool symtrace = TRUE;
static void m68k_sim_init(void);
static t_stat hdump_cmd(int32 arg,char* buf);
static t_stat symset_cmd(int32 arg,char* buf);
static t_stat symclr_cmd(int32 arg,char* buf);
static t_stat symlist_cmd(int32 arg,char* buf);
static t_stat symtrace_cmd(int32 arg,char* buf);
static CTAB m68k_sim_cmds[] = {
{"STEP", &run_cmd, RU_STEP,
"s{tep} {n} simulate n instructions\n" },
{"HEXDUMP", &hdump_cmd, 0,
"hex{dump} range dump memory\n" },
{"SYMSET", &symset_cmd, 0,
"syms{et} name=value define symbolic name for disassembler/tracer\n"},
{"SYMCLR",&symclr_cmd, 0,
"symc{lr} {-a|name} clear symbolic name / all symbolic names\n"},
{"SYMLIST", &symlist_cmd, 0,
"syml{ist} [name] list symbol table\n"},
{"SYMTRACE", &symtrace_cmd, 1,
"symt{race} enable symbolic tracing\n"},
{"NOSYMTRACE", &symtrace_cmd, 0,
"nosymt{race} disable symbolic tracing\n"},
{0,0,0,0}
};
void (*sim_vm_init)(void) = &m68k_sim_init;
typedef struct _symhash {
struct _symhash* nnext;
struct _symhash* vnext;
char* name;
t_addr val;
} SYMHASH;
#define SYMHASHSIZE 397
static SYMHASH *symbyname = 0;
static SYMHASH *symbyval = 0;
static void sym_clearall(void)
{
int i;
SYMHASH *p,*n;
if (!symbyname) return;
for (i=0; i<SYMHASHSIZE; i++) {
p = symbyname[i].nnext;
while ((n = p) != 0) {
p = p->nnext;
free(n->name);
free(n);
}
symbyname[i].nnext = symbyval[i].vnext = 0;
}
return;
}
static void m68k_sim_init(void)
{
int i;
sim_vm_cmd = m68k_sim_cmds;
sym_clearall();
symbyname = (SYMHASH*)calloc(sizeof(SYMHASH),SYMHASHSIZE);
symbyval = (SYMHASH*)calloc(sizeof(SYMHASH),SYMHASHSIZE);
for (i=0; i<SYMHASHSIZE; i++)
symbyval[i].vnext = symbyname[i].nnext = 0;
symtrace = TRUE;
}
static int getnhash(const char* name)
{
int i, nhash = 0;
for (i=0; name[i]; i++) {
nhash += name[i];
}
return nhash % SYMHASHSIZE;
}
static int getvhash(t_addr val)
{
return val % SYMHASHSIZE;
}
static t_bool sym_lookupname(const char *name,SYMHASH **n)
{
int hash = getnhash(name);
SYMHASH *p = symbyname[hash].nnext;
while (p && strcmp(name,p->name)) p = p->nnext;
*n = p;
return p != 0;
}
static t_bool sym_lookupval(t_addr val, SYMHASH **v)
{
int hash = getvhash(val);
SYMHASH *p = symbyval[hash].vnext;
while (p && p->val != val) p = p->vnext;
*v = p;
return p != 0;
}
static t_bool sym_enter(const char* name,t_addr val)
{
int nhash = getnhash(name);
int vhash = getvhash(val);
SYMHASH *v, *n, *e;
if (sym_lookupname(name,&n) || sym_lookupval(val,&v)) return FALSE;
n = symbyname[nhash].nnext;
v = symbyval[vhash].vnext;
e = (SYMHASH*)malloc(sizeof(SYMHASH));
e->nnext = n;
e->vnext = v;
e->name = malloc(strlen(name)+1);
strcpy(e->name,name);
e->val = val;
symbyname[nhash].nnext = symbyval[vhash].vnext = e;
return TRUE;
}
static t_bool sym_delete(const char* name)
{
int hash = getnhash(name);
SYMHASH *p, *q, **n, **v;
n = &symbyname[hash].nnext;
while ((p = *n) != 0) {
if (!strcmp(p->name,name)) { /*found*/
hash = getvhash(p->val);
v = &symbyval[hash].vnext;
while ((q = *v) != 0) {
if (q->val == p->val) { /*found*/
*v = q->vnext;
break;
}
v = &(q->vnext);
}
*n = p->nnext;
free(p->name);
free(p);
return TRUE;
}
}
return FALSE;
}
static t_stat symset_cmd(int32 arg,char* buf)
{
char *name,*vstr;
t_addr val;
if ((name = strtok(buf, "= ")) == 0) return SCPE_2FARG;
if ((vstr = strtok(NULL, " \t\n")) == 0) return SCPE_2FARG;
val = strtol(vstr, 0, 16);
if (!sym_enter(name, val))
printf("Name or value already exists\n");
return SCPE_OK;
}
static t_stat symclr_cmd(int32 arg,char* buf)
{
char* token;
if (buf[0] == '-' && buf[1]=='a') {
sym_clearall();
return SCPE_OK;
} else {
token = strtok(buf," \t\n");
if (!token) return SCPE_2FARG;
return sym_delete(token) ? SCPE_OK : SCPE_ARG;
}
}
static t_stat symlist_cmd(int32 arg,char* buf)
{
int i;
SYMHASH* n;
char *name;
t_bool found = FALSE;
name = strtok(buf," \t\n");
if (name) {
if (sym_lookupname(name,&n))
printf(" %s = 0x%08x\n",n->name,n->val);
else
printf("Unknown\n");
} else {
for (i=0; i<SYMHASHSIZE; i++) {
n = symbyname[i].nnext;
while (n) {
printf(" %s = 0x%08x\n",n->name,n->val);
n = n->nnext;
found = TRUE;
}
}
if (!found) printf("Symbol table is empty\n");
}
return SCPE_OK;
}
static t_stat symtrace_cmd(int32 arg,char* buf)
{
if (!*buf)
symtrace = arg ? TRUE : FALSE;
printf("Symbolic tracing %sabled\n",symtrace ? "en" : "dis");
return SCPE_OK;
}
static void putascii(uint32* buf)
{
int i;
putchar('|');
for (i=0; i<16; i++) {
if (isprint(buf[i])) putchar(buf[i]);
else putchar('.');
}
putchar('|');
}
static t_stat hdump_cmd(int32 arg, char* buf)
{
int i;
t_addr low, high, base, top;
char *token;
uint32 byte[16];
t_bool ascii = FALSE;
t_bool first = TRUE;
if (buf[0]=='-' && buf[1]=='a') {
ascii = TRUE;
buf += 2;
while (*buf && isspace(*buf)) buf++;
}
memset(byte,0,sizeof(uint32)*16);
token = strtok(buf,"- \t\n");
if (!token) return SCPE_2FARG;
low = strtol(token,0,16);
token = strtok(NULL,"- \t\n");
if (!token) return SCPE_2FARG;
high = strtol(token,0,16);
base = low - (low % 16);
top = (high + 15) - ((high+15) % 16);
for (; base<top; base++) {
if ((base % 16)==0) {
if (!first && ascii) putascii(byte);
printf("\n%08x: ",base);
first = FALSE;
}
if (base < low) printf(" ");
else if (base > high) printf(" ");
else {
i = base %16;
if (ReadPB(base,byte+i) != SCPE_OK) printf("?? ");
else printf("%02x ",byte[i] & 0xff);
}
}
if (!first && ascii) putascii(byte);
putchar('\n');
return SCPE_OK;
}
char* m68k_getsym(t_addr val,const char* fmt, char* outbuf)
{
SYMHASH *v;
if (symtrace && sym_lookupval(val,&v))
return v->name;
else {
sprintf(outbuf,fmt,val);
return outbuf;
}
}

999
SAGE/m68k_sys.c Normal file
View file

@ -0,0 +1,999 @@
/* m68k_sys.c: assembler/disassembler/misc simfuncs for generic m68k_cpu
Copyright (c) 2009, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
15-Mar-10 HV fix 2nd arg bug in disassembling btst
24-Apr-10 HV fix _fsymea for jsr.l
27-Apr-10 HV fix stop instr
27-Jun-10 HV improve error handling in Motorola S0 reader
20-Jul-10 HV fix disassemble error for LINK
*/
#include "m68k_cpu.h"
#include <ctype.h>
#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#endif
t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc)
{
DEVICE* dptr;
PNP_INFO* pnp;
t_stat rc;
uint16 newbase;
if (!cptr) return SCPE_ARG;
if (!uptr) return SCPE_IERR;
if (!(dptr = find_dev_from_unit(uptr))) return SCPE_IERR;
if (!(pnp = (PNP_INFO*)dptr->ctxt)) return SCPE_IERR;
newbase = get_uint (cptr, 16, 0xFF, &rc);
if (rc != SCPE_OK) return rc;
if (dptr->flags & DEV_DIS) {
printf("Device not enabled yet.\n");
pnp->io_base = newbase;
} else {
dptr->flags |= DEV_DIS;
dptr->reset(dptr);
pnp->io_base = newbase;
dptr->flags &= ~DEV_DIS;
dptr->reset(dptr);
}
return SCPE_OK;
}
t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc)
{
DEVICE *dptr;
PNP_INFO *pnp;
if (!uptr) return SCPE_IERR;
if (!(dptr = find_dev_from_unit(uptr))) return SCPE_IERR;
if (!(pnp = (PNP_INFO *) dptr->ctxt)) return SCPE_IERR;
fprintf(st, "I/O=0x%02X-0x%02X", pnp->io_base, pnp->io_base + pnp->io_size - pnp->io_incr);
return SCPE_OK;
}
t_stat m68k_set_cpu(UNIT *uptr, int32 value, char *cptr, void *desc)
{
if (value < 0 || value > CPU_TYPE_68030)
return SCPE_ARG;
cputype = (value & UNIT_CPUTYPE_MASK) >> UNIT_CPU_V_TYPE;
uptr->flags &= ~UNIT_CPUTYPE_MASK;
uptr->flags |= value;
return SCPE_OK;
}
t_stat m68k_show_cpu(FILE* st,UNIT *uptr, int32 value, void *desc)
{
fprintf(st,"TYPE=%s",(char*)desc);
return SCPE_OK;
}
t_stat m68k_alloc_mem()
{
if (M == NULL)
M = (uint8*)calloc(MEMORYSIZE, 1);
else
M = (uint8*)realloc(M, MEMORYSIZE);
return M == NULL ? SCPE_MEM : SCPE_OK;
}
t_stat m68k_set_size(UNIT *uptr, int32 value, char *cptr, void *desc)
{
t_stat rc;
uptr->capac = value;
if ((rc=m68k_alloc_mem()) != SCPE_OK) return rc;
return SCPE_OK;
}
t_stat m68k_set_fpu(UNIT *uptr, int32 value, char *cptr, void *desc)
{
uptr->flags |= value;
return SCPE_OK;
}
t_stat m68k_set_nofpu(UNIT *uptr, int32 value, char *cptr, void *desc)
{
uptr->flags |= value;
return SCPE_OK;
}
t_stat m68kcpu_set_flag(UNIT *uptr, int32 value, char *cptr, void *desc)
{
uptr->flags |= value;
return SCPE_OK;
}
t_stat m68kcpu_set_noflag(UNIT *uptr, int32 value, char *cptr, void *desc)
{
uptr->flags &= ~value;
return SCPE_OK;
}
t_stat m68kcpu_ex(t_value* eval_array, t_addr addr, UNIT* uptr, int32 sw)
{
uint32 val = 0;
t_stat rc = (sw & SWMASK('V')) ? ReadVW(addr,&val) : ReadPW(addr,&val);
if (rc==SCPE_OK) *eval_array = val;
return rc;
}
t_stat m68kcpu_dep(t_value value, t_addr addr, UNIT* uptr, int32 sw)
{
return (sw & SWMASK('V')) ? WriteVW(addr,value) : WritePW(addr,value);
}
static int getHex(FILE* fptr,int* chksum)
{
char buf[3];
int c;
if ((c = fgetc(fptr))==EOF) return EOF;
buf[0] = c;
if ((c = fgetc(fptr))==EOF) return EOF;
buf[1] = c;
buf[2] = 0;
return strtol(buf,0,16);
}
/* Motorola S-Record reader
* Format:
* type 2 Bytes (S0, S1, S2, S3, S5, S7, S8, S9)
* reclength 2 Bytes
* address 4,6,8 Bytes
* data 0...2n
* checksum 2 Bytes (lsb of 1'comp of fields reclength-data
*/
static t_stat m68k_sread(FILE* fptr)
{
int typ;
t_addr addr=0, a;
int d, len, chksum, i;
int end = FALSE;
int line = 0;
fseek(fptr,0l,SEEK_SET);
for(;;) {
while ((i = fgetc(fptr)) == '\r' || i == '\n');
line++;
if (end && i == EOF) return SCPE_OK;
if (i != 'S') { printf("Line %d: expected S but did not find one (found %x)\n",line,i); return SCPE_FMT; }
typ = fgetc(fptr);
chksum = 0;
len = getHex(fptr,&chksum);
addr = getHex(fptr,&chksum);
a = getHex(fptr,&chksum);
if (len==EOF || addr==EOF || a==EOF) { typ = 'X'; goto error; }
addr = (addr << 8) | a;
i = 3;
switch (typ) {
case '0':
for (i=2; i<len; i++) (void)getHex(fptr,&chksum);
break;
case '1':
i = 2;
goto dread;
case '3':
if ((a = getHex(fptr,&chksum))==EOF) goto error;
addr = (addr << 8) | a;
i = 4;
/*fallthru*/
case '2':
if ((a = getHex(fptr,&chksum))==EOF) goto error;
addr = (addr << 8) | a;
dread:
for (; i<len; i++) { d = getHex(fptr,&chksum); WritePB(addr,d); addr++; }
break;
case '7':
if ((a = getHex(fptr,&chksum))==EOF) goto error;
addr = (addr << 8) | a;
/*fallthru*/
case '8':
if ((a = getHex(fptr,&chksum))==EOF) goto error;
addr = (addr << 8) | a;
/*fallthru*/
case '9':
end = TRUE;
/*fallthru*/
case '5':
if((d = getHex(fptr,&chksum))==EOF) goto error;
break;
}
if ((chksum & 0xff) != 0) return SCPE_CSUM;
saved_PC = addr;
}
error:
printf("S%c at line %d: Unexpected EOF/Invalid character\n",typ,line);
return SCPE_FMT;
}
t_stat sim_load(FILE* fptr, char* cptr, char* fnam, t_bool flag)
{
int i,len,rc;
uint16 data;
uint8 s;
int32 addr = saved_PC;
/* no dump */
if (*cptr != 0 || flag != 0) return SCPE_ARG;
/* check whether Motorola S-Record format was presented */
fseek(fptr,0L,SEEK_SET);
if (fread(&s,sizeof(uint8),1,fptr) == 1) {
if (s == 'S') {
/* asssume S record format */
if (m68k_sread(fptr) == SCPE_OK) return SCPE_OK;
}
}
/* assume plain octet word stream */
fseek(fptr,0L,SEEK_END);
len = ftell(fptr);
if (len & 1) return SCPE_FMT;
fseek(fptr,0L,SEEK_SET);
for (i=0; i<len; i+=2) {
if (fread(&data,sizeof(uint16),1,fptr) != 1) return SCPE_FMT;
if ((rc=WritePW(addr,data)) != SCPE_OK) return rc;
addr += 2;
}
return SCPE_OK;
}
const char *sim_stop_messages[] = {
"---",
"PC Breakpoint",
"MEM Breakpoint",
"Invalid Opcode",
"Invalid I/O address",
"Invalid Mem access",
"Not yet implemented!",
"(internal: IO dispatch)",
"(internal: nonexisting memory)",
"PC at I/O address",
"Privilege Violation",
"Trace trap",
"STOP instruction",
"Double Bus Fault",
"Printer Offline",
};
#define ONERR_QUIT() if (rc==SCPE_ARG) { printf("??\n\t"); return SCPE_ARG; }
#define REG0_FIELD(inst) (inst&7)
#define REG0_CHAR(inst) (inst&7) + '0'
#define REG9_CHAR(inst) ((inst>>9)&7) + '0'
#define OPLEN_FIELD(inst) (inst>>6)&3
#define EA_FIELD(inst) inst&077
#define EAMOD_FIELD(inst) inst & 070
#define BWL_CHAR(oplen) (oplen==0) ? 'b' : ((oplen==1) ? 'w' : 'l')
#define DATA_B(x) (x&0xff)
#define DATA_W(x) (x&0xffff)
static t_stat _fsymea(FILE* of,t_addr addr,int ea, int oplen,t_value* rest)
{
int eamod = EAMOD_FIELD(ea);
char eareg = REG0_CHAR(ea);
t_value offb = DATA_B(rest[0]);
t_value offw = DATA_W(rest[0]);
t_value offw2 = DATA_W(rest[1]);
char da = (rest[0] & 0x8000)? 'a' : 'd';
char xreg = ((rest[0]>>12) & 7) + '0';
char wl = (rest[0] & 0x800) ? 'l' : 'w';
switch (eamod) {
case 000: fprintf(of,"d%c",eareg); return 0;
case 010: fprintf(of,"a%c",eareg); return 0;
case 020: fprintf(of,"(a%c)",eareg); return 0;
case 030: fprintf(of,"(a%c)+",eareg); return 0;
case 040: fprintf(of,"-(a%c)",eareg); return 0;
case 050: fprintf(of,"($%x,a%c)",offw,eareg); return -2;
case 060:
if (offb)
fprintf(of,"($%x,a%c,%c%c.%c)",offb,eareg,da,xreg,wl);
else
fprintf(of,"(a%c,%c%c.%c)",eareg,da,xreg,wl);
return -2;
case 070:
switch (eareg) {
case '0': fprintf(of,"($%x).w",(uint32)((uint16)offw)); return -2;
case '1':
if (offw)
fprintf(of,"($%x%04x).l",offw,offw2);
else
fprintf(of,"($%x).l",offw2);
return -4;
case '2': //fprintf(of,"($%x,pc)",offw);
if (offw & 0x8000) offw |= 0xffff0000;
fprintf(of,"$%x",addr+offw+2);
return -2;
case '3':
if (offb)
fprintf(of,"($%x,pc,%c%c.%c)",offb,da,xreg,wl);
else
fprintf(of,"(pc,%c%c.%c)",da,xreg,wl);
return -2;
case '4':
switch(oplen) {
case 0: fprintf(of,"#$%x",offb); return -2;
case 1: fprintf(of,"#$%x",offw); return -2;
case 2:
if (offw)
fprintf(of,"#$%x%04x",offw,offw2);
else
fprintf(of,"#$%x",offw2);
return -4;
case 3: fprintf(of,"ccr"); return 0;
case 4: fprintf(of,"sr"); return 0;
default: return SCPE_ARG;
}
default: return SCPE_ARG;
}
default: return SCPE_ARG;
}
}
static t_stat _fsymead(FILE* of,int dir,char reg9,t_addr addr,int ea,int oplen,t_value* rest)
{
int rc;
if (dir) {
fprintf(of,"d%c,",reg9); rc = _fsymea(of,addr,ea,oplen,rest);
} else {
rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT(); fprintf(of,",d%c",reg9);
}
return rc-1;
}
static t_stat _fsymimm(FILE* of,int oplen,t_value* rest)
{
t_value offb = rest[0] & 0xff;
t_value offw = rest[0] & 0xffff;
t_value offw2 = rest[1] & 0xffff;
switch(oplen) {
case 0: fprintf(of,"#$%x",offb); return 1;
case 1: fprintf(of,"#$%x",offw); return 1;
case 2: fprintf(of,"#$%x%04x",offw,offw2); return 2;
default: return SCPE_ARG;
}
}
static t_stat _fsym0(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
int rc;
int oplen = OPLEN_FIELD(inst);
char bwl = BWL_CHAR(oplen);
char reg9 = REG9_CHAR(inst);
char reg0 = REG0_CHAR(inst);
int bitnum= DATA_B(rest[0]);
int ea = EA_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
char* s = 0;
switch (inst & 000700) {
case 000400:
if (eamod==010) {
fprintf(of,"movep.w $%x(a%c),d%c",rest[0],reg0,reg9); return -3;
} else s = "btst";
break;
case 000500:
if (eamod==010) {
fprintf(of,"movep.l $%x(a%c),d%c",rest[0],reg0,reg9); return -3;
} else s = "bchg";
break;
case 000600:
if (eamod==010) {
fprintf(of,"movep.w d%c,$%x(a%c)",reg9,rest[0],reg0); return -3;
} else s = "bclr";
break;
case 000700:
if (eamod==010) {
fprintf(of,"movep.l d%c,$%x(a%c)",reg9,rest[0],reg0); return -3;
} else s = "bset";
break;
}
if (s) {
fprintf(of,"%s d%c,",s,reg9); rc = _fsymea(of,addr,ea,3,rest); ONERR_QUIT(); return rc-1;
}
switch (inst & 007000) {
case 000000:
s = "ori"; break;
case 001000:
s = "andi"; break;
case 002000:
s = "subi"; break;
case 003000:
s = "addi"; break;
case 004000:
switch (inst & 000700) {
case 000000:
s = "btst"; break;
case 000100:
s = "bchg"; break;
case 000200:
s = "bclr"; break;
case 000300:
s = "bset"; break;
default:
return SCPE_ARG;
}
fprintf(of,"%s #%x,",s,bitnum); rc = _fsymea(of,addr,ea,0,rest+1); ONERR_QUIT(); return rc-3;
case 005000:
s = "eori"; break;
case 006000:
s = "cmpi"; break;
default:
return SCPE_ARG;
}
fprintf(of,"%s.%c ",s,bwl); rc = _fsymimm(of,oplen,rest); ONERR_QUIT();
fputc(',',of); rc = _fsymea(of,addr,ea,oplen+3,rest+rc);
return rc - 3 - ((oplen==2) ? 2 : 0);
}
static t_stat _fsym123(FILE* of,t_value inst,t_addr addr,t_value* rest,char w,int oplen)
{
int rc, rc2;
int eas = inst & 077;
int eat = ((inst>>9)&7)|((inst&0700)>>3);
char *s = ((eat&070)==010) ? "movea" : "move";
fprintf(of,"%s.%c ",s,w);
rc = _fsymea(of,addr,eas,oplen,rest); ONERR_QUIT(); rc2 = rc;
fputc(',',of);
rc = _fsymea(of,addr,eat,oplen,rest-rc2/2); ONERR_QUIT();
return rc2 + rc -1;
}
static char* moveregs[] = {
"d0","d1","d2","d3","d4","d5","d6","d7","a0","a1","a2","a3","a4","a5","a6","a7"
};
static char* moveregsp[] = {
"a7","a6","a5","a4","a3","a2","a1","a0","d7","d6","d5","d4","d3","d2","d1","d0"
};
#define BITEMIT() if (sl) fputc('/',of); sl = 1; \
if (hi==lo) fprintf(of,"%s",regs[lo]); \
else if (ispredec) fprintf(of,"%s-%s",regs[hi],regs[lo]); \
else fprintf(of,"%s-%s",regs[lo],regs[hi]); \
lo = hi = -1;
#define BITSEQ() bit = regset & 1; regset >>= 1; \
if (bit && lo == -1) lo = i; \
if (bit == 0 && lo != -1) { hi = i-1; BITEMIT(); }
static void _fsymregs(FILE* of, int regset,int ispredec)
{
int lo, hi, bit, sl, i;
char** regs = ispredec ? moveregsp : moveregs;
//printf("regset=%x\n",regset);
sl = 0;
bit = lo = hi = -1;
for (i=0; i<8; i++) { BITSEQ(); }
if (lo != -1) { hi = 7; BITEMIT(); }
bit = -1;
for (i=8; i<16; i++) { BITSEQ(); }
if (lo != -1) { hi = 15; BITEMIT(); }
}
static t_stat _fsym4(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
t_stat rc;
char reg9 = REG9_CHAR(inst);
int ea = EA_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
char reg0 = REG0_CHAR(inst);
int oplen = OPLEN_FIELD(inst);
char* s;
switch (inst & 000700) {
case 000600:
fprintf(of,"chk "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT();
fprintf(of,",d%c",reg9); return rc-1;
case 000700:
fprintf(of,"lea "); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9); return rc-1;
case 000000:
switch (inst & 007000) {
case 000000:
s = "negx.b "; break;
case 001000:
s = "clr.b "; break;
case 002000:
s = "neg.b "; break;
case 003000:
s = "not.b "; break;
case 004000:
s = "nbcd "; break;
case 005000:
s = "tst.b "; break;
default:
return SCPE_ARG;
}
fputs(s,of); rc = _fsymea(of,addr,ea,0,rest); ONERR_QUIT(); return rc-1;
case 000100:
switch (inst & 007000) {
case 007000:
switch (inst & 000070) {
case 000000:
case 000010:
fprintf(of,"trap #$%x",inst & 0xf); return -1;
case 000020:
fprintf(of,"link a%c,#$%x",reg0,rest[0]); return -3;
case 000030:
fprintf(of,"unlk a%c",reg0); return -1;
case 000040:
fprintf(of,"move a%c,usp",reg0); return -1;
case 000050:
fprintf(of,"move usp,a%c",reg0); return -1;
case 000060:
switch (inst & 000007) {
case 000000:
s = "reset"; break;
case 000001:
s = "nop"; break;
case 000002:
fprintf(of,"stop #%x",DATA_W(rest[0])); return -3;
case 000003:
s = "rte"; break;
case 000005:
s = "rts"; break;
case 000006:
s = "trapv"; break;
case 000007:
s = "rtr"; break;
default:
return SCPE_ARG;
}
fputs(s,of); return -1;
default:
return SCPE_ARG;
}
case 000000:
s = "negx.w "; break;
case 001000:
s = "clr.w "; break;
case 002000:
s = "neg.w "; break;
case 003000:
s = "not.w "; break;
case 005000:
s = "tst.w "; break;
case 004000:
if (eamod==0) {
fprintf(of,"swap d%c",reg0); return -1;
} else {
fputs("pea ",of); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT(); return rc-1;
}
default:
return SCPE_ARG;
}
fputs(s,of); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT(); return rc-1;
case 000200:
switch (inst & 007000) {
case 000000:
s = "negx.l "; break;
case 001000:
s = "clr.l "; break;
case 002000:
s = "neg.l "; break;
case 003000:
s = "not.l "; break;
case 004000:
if (eamod==0) {
fprintf(of,"ext.w d%c",reg0); return -1;
} else {
fprintf(of,"movem.w "); _fsymregs(of,rest[0],eamod==040);
fputc(',',of); rc = _fsymea(of,addr,ea,oplen==2?1:2,rest+1); return rc-3;
}
case 005000:
s = "tst.l "; break;
case 006000:
fprintf(of,"movem.w "); rc = _fsymea(of,addr,ea,oplen==2?1:2,rest+1);
fputc(',',of); _fsymregs(of,rest[0],0); return rc-3;
case 007000:
s = "jsr "; break;
default:
return SCPE_ARG;
}
fputs(s,of); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT(); return rc-1;
case 000300:
switch (inst & 007000) {
case 000000:
fprintf(of,"move sr,"); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT(); return rc-1;
case 003000:
fprintf(of,"move "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT(); fputs(",sr",of); return rc-1;
case 002000:
fprintf(of,"move "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT(); fputs(",ccr",of); return rc-1;
case 004000:
if (eamod==0) {
fprintf(of,"ext.l d%c",reg0); return -1;
} else {
fprintf(of,"movem.l "); _fsymregs(of,rest[0],eamod==040);
fputc(',',of); rc = _fsymea(of,addr,ea,oplen==2?1:2,rest+1); return rc-3;
}
case 005000:
switch (inst & 000077) {
case 000074:
fputs("illegal",of); return -1;
default:
fprintf(of,"tas "); rc = _fsymea(of,addr,ea,0,rest); return rc-1;
}
case 006000:
fprintf(of,"movem.l "); rc = _fsymea(of,addr,ea,oplen==2?1:2,rest+1);
fputc(',',of); _fsymregs(of,rest[0],0); return rc-3;
case 007000:
fputs("jmp ",of); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT(); return rc-1;
default:
return SCPE_ARG;
}
default:
return SCPE_ARG;
}
}
static char* conds[] = { "ra","sr","hi","ls","cc","cs","ne","eq","vc","vs","pl","mi","ge","lt","gt","le" };
static char* conds2[] = { "t", "f","hi","ls","cc","cs","ne","eq","vc","vs","pl","mi","ge","lt","gt","le" };
static t_stat _fsym5(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
t_stat rc;
int ea = EA_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
int reg0 = REG0_CHAR(inst);
int oplen = OPLEN_FIELD(inst);
char bwl = BWL_CHAR(oplen);
t_addr a;
if (oplen==3) {
char* cond = conds2[(inst>>8)&0xf];
if (eamod==010) {
a = rest[0] & 0xffff;
if (a & 0x8000) a |= 0xffff0000;
//printf("addr=%x a=%x sum=%x\n",addr,a,addr+a+2);
fprintf(of,"db%s d%c,$%x",cond,reg0,addr+a+2);
return -3;
} else {
fprintf(of,"s%s ",cond); rc = _fsymea(of,addr,ea,0,rest); return rc-3;
}
} else {
int data = (inst>>9) & 07;
char *s = (inst & 0x0100) ? "subq" : "addq";
if (data==0) data = 8;
fprintf(of,"%s.%c #%d,",s,bwl,data); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT(); return rc-1;
}
}
static t_stat _fsym6(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
char* cond = conds[(inst>>8)&0xf];
t_addr a = inst & 0xff;
if (a) {
if (a & 0x80) a |= 0xffffff00;
fprintf(of,"b%s.s $%x",cond,addr+a+2); return -1;
} else {
a = rest[0] & 0xffff;
if (a & 0x8000) a |= 0xffff0000;
fprintf(of,"b%s.w $%x",cond,addr+a+2); return -3;
}
}
static t_stat _fsym7(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
int reg9 = REG9_CHAR(inst);
switch (inst & 000400) {
case 000000:
fprintf(of,"moveq #$%x,d%c",(int32)((int8)(inst&0xff)),reg9); return -1;
default:
return SCPE_ARG;
}
}
static t_stat _fsym8(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
t_stat rc;
int oplen = OPLEN_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
int ea = EA_FIELD(inst);
char reg9 = REG9_CHAR(inst);
char reg0 = REG0_CHAR(inst);
char bwl = BWL_CHAR(oplen);
switch (inst & 000700) {
case 000000:
case 000100:
case 000200:
fprintf(of,"or.%c ",bwl); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT();
fprintf(of,",d%c",reg9); return rc-1;
case 000300:
fprintf(of,"divu.w "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT();
fprintf(of,",d%c",reg9); return rc-1;
case 000400:
switch (eamod) {
case 000:
fprintf(of,"sbcd d%c,d%c",reg0,reg9); return -1;
case 010:
fprintf(of,"sbcd -(a%c),-(a%c)",reg0,reg9); return -1;
default:
fprintf(of,"or.%c d%c,",bwl,reg9); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT();
return rc-1;
}
case 000500:
case 000600:
fprintf(of,"or.%c d%c,",bwl,reg9); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT();
return rc-1;
case 000700:
fprintf(of,"divs.w "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT();
fprintf(of,",d%c",reg9); return rc-1;
}
return SCPE_ARG; /* Not reached, but silence agressive compiler warnings */
}
static t_stat _fsym9(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
t_stat rc;
int oplen = OPLEN_FIELD(inst);
char reg9 = REG9_CHAR(inst);
char reg0 = REG0_CHAR(inst);
char bwl = BWL_CHAR(oplen);
int ea = EA_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
switch (inst & 000700) {
case 000000:
case 000100:
case 000200:
fprintf(of,"sub.%c ",bwl); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT();
fprintf(of,",d%c",reg9);return rc-1;
case 000300:
fprintf(of,"suba.w "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9);return rc-1;
case 000400:
switch (eamod) {
case 000:
fprintf(of,"subx.%c d%c,d%c",bwl,reg9,reg0); return -1;
case 001:
fprintf(of,"subx.%c d%c,d%c",bwl,reg9,reg0); return -1;
default:
fprintf(of,"sub.%c d%c,",bwl,reg9); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT(); return rc-1;
}
case 000500:
case 000600:
fprintf(of,"sub.%c d%c,",bwl,reg9); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT(); return rc-1;
case 000700:
fprintf(of,"suba.l "); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9);return rc-1;
default:
return SCPE_ARG;
}
}
static t_stat _fsyma(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
fprintf(of,"trapa #$%x",inst&0xfff); return -1;
}
static t_stat _fsymb(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
int rc;
char reg9 = REG9_CHAR(inst);
char reg0 = REG0_CHAR(inst);
int ea = EA_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
int oplen = OPLEN_FIELD(inst);
char bwl = BWL_CHAR(oplen);
switch (inst & 000700) {
case 000000:
case 000100:
case 000200:
fprintf(of,"cmp.%c ",bwl); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT();
fprintf(of,",d%c",reg9); return rc-1;
case 000300:
fprintf(of,"cmpa.w "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9); return rc-1;
case 000400:
case 000500:
case 000600:
if (eamod==010) {
fprintf(of,"cmpm.%c (a%c)+,(a%c)+",bwl,reg0,reg9); return -1;
} else {
fprintf(of,"eor.%c d%c,",bwl,reg9); rc = _fsymea(of,addr,ea,oplen,rest); ONERR_QUIT();
return rc-1;
}
case 000700:
fprintf(of,"cmpa.l "); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9); return rc-1;
default:
return SCPE_ARG;
}
}
static t_stat _fsymc(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
char reg9 = REG9_CHAR(inst);
int ea = EA_FIELD(inst);
int reg0 = REG0_CHAR(inst);
int oplen = OPLEN_FIELD(inst);
char bwl = BWL_CHAR(oplen);
switch (inst & 0000770) {
case 0000500:
fprintf(of,"exg d%c,d%c",reg9,reg0); return -1;
case 0000510:
fprintf(of,"exg a%c,a%c",reg9,reg0); return -1;
case 0000610:
fprintf(of,"exg d%c,a%c",reg9,reg0); return -1;
case 0000400:
fprintf(of,"abcd d%c,d%c",reg9,reg0); return -1;
case 0000410:
fprintf(of,"abcd -(a%c),-(a%c)",reg9,reg0); return -1;
default:
break;
}
switch (inst & 0000700) {
case 0000400:
fprintf(of,"and.%c ",bwl); return _fsymead(of,1,reg9,addr,ea,oplen,rest);
case 0000000:
case 0000100:
case 0000200:
fprintf(of,"and.%c ",bwl); return _fsymead(of,0,reg9,addr,ea,oplen,rest);
case 0000300:
fprintf(of,"mulu.w "); return _fsymead(of,0,reg9,addr,ea,1,rest);
case 0000700:
fprintf(of,"muls.w "); return _fsymead(of,0,reg9,addr,ea,1,rest);
default:
return SCPE_ARG;
}
}
static t_stat _fsymd(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
int rc;
char reg9 = REG9_CHAR(inst);
char reg0 = REG0_CHAR(inst);
int ea = EA_FIELD(inst);
int eamod = EAMOD_FIELD(inst);
int oplen = OPLEN_FIELD(inst);
char bwl = BWL_CHAR(oplen);
switch (inst & 000700) {
case 000000:
case 000100:
case 000200:
fprintf(of,"add.%c ",bwl); return _fsymead(of,0,reg9,addr,ea,oplen,rest);
case 000300:
fprintf(of,"adda.w "); rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9); return rc-1;
case 000400:
switch (eamod) {
case 000:
fprintf(of,"addx.%c d%c,d%c",bwl,reg9,reg0); return -1;
case 001:
fprintf(of,"addx.%c d%c,d%c",bwl,reg9,reg0); return -1;
default:
fprintf(of,"add.%c ",bwl); return _fsymead(of,1,reg9,addr,ea,oplen,rest);
}
case 000500:
case 000600:
fprintf(of,"add.%c ",bwl); return _fsymead(of,1,reg9,addr,ea,oplen,rest);
case 000700:
fprintf(of,"adda.l "); rc = _fsymea(of,addr,ea,2,rest); ONERR_QUIT();
fprintf(of,",a%c",reg9); return rc-1;
}
return SCPE_ARG; /* Not reached, but silence agressive compiler warnings */
}
static t_stat _fsyme(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
int rc;
int oplen = OPLEN_FIELD(inst);
char bwl = BWL_CHAR(oplen);
int op = (oplen==3 ? (inst>>9) : (inst>>3)) & 3;
char dir = (inst&0x100) ? 'l' : 'r';
int ir = inst & 0x20;
int ea = EA_FIELD(inst);
char reg9 = REG9_CHAR(inst);
char reg0 = REG0_CHAR(inst);
char *s;
switch (op) {
case 0: s = "as"; break;
case 1: s = "ls"; break;
case 2: s = "rox"; break;
case 3: s = "ro"; break;
default: s = "??"; break;
}
fprintf(of,"%s%c",s,dir);
if (oplen<3) {
fprintf(of,".%c ",bwl);
if (ir)
fprintf(of,"d%c,d%c",reg9,reg0);
else {
if (reg9=='0') reg9 = '8';
fprintf(of,"#%d,d%c",reg9-'0',reg0);
}
return -1;
} else {
fputc(' ',of);
rc = _fsymea(of,addr,ea,1,rest); ONERR_QUIT(); return rc-1;
}
}
static t_stat _fsymf(FILE* of,t_value inst,t_addr addr,t_value* rest)
{
fprintf(of,"trapf #$%x",inst&0xfff); return -1;
}
t_stat fprint_sym(FILE* of, t_addr addr, t_value* val, UNIT* uptr, int32 sw)
{
int32 c1, c2, inst;
c1 = (val[0] >> 8) & 0177;
c2 = val[0] & 0177;
if (sw & SWMASK ('A')) {
fprintf (of, (c2 < 040)? "<%02x>": "%c", c2);
return SCPE_OK;
}
if (sw & SWMASK ('C')) {
fprintf (of, (c1 < 040)? "<%02x>": "%c", c1);
fprintf (of, (c2 < 040)? "<%02x>": "%c", c2);
return -1;
}
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
inst = val[0];
switch ((inst>>12) & 0xf) {
case 0x0: return _fsym0(of,inst,addr,val+1);
case 0x1: return _fsym123(of,inst,addr,val+1,'b',0);
case 0x2: return _fsym123(of,inst,addr,val+1,'l',2);
case 0x3: return _fsym123(of,inst,addr,val+1,'w',1);
case 0x4: return _fsym4(of,inst,addr,val+1);
case 0x5: return _fsym5(of,inst,addr,val+1);
case 0x6: return _fsym6(of,inst,addr,val+1);
case 0x7: return _fsym7(of,inst,addr,val+1);
case 0x8: return _fsym8(of,inst,addr,val+1);
case 0x9: return _fsym9(of,inst,addr,val+1);
case 0xa: return _fsyma(of,inst,addr,val+1);
case 0xb: return _fsymb(of,inst,addr,val+1);
case 0xc: return _fsymc(of,inst,addr,val+1);
case 0xd: return _fsymd(of,inst,addr,val+1);
case 0xe: return _fsyme(of,inst,addr,val+1);
case 0xf: return _fsymf(of,inst,addr,val+1);
}
return SCPE_OK;
}

91
SAGE/readme-sage.txt Normal file
View file

@ -0,0 +1,91 @@
This is version 0.5 of a simulator for the SAGE-68K computer. See www.sageandstride.org for details.
This is called Version 0.5 because it still lacks a few things and has a number of known bugs.
Features and problems
- currently is at the level of a SAGE-II system with two floppy drives
- Currently runs CP/M-68K 1.2 (IMD-Disk included)
- Console and SIO can be redirected to a telnet session
- does not run UCSD-Pascal yet (in progress)
- does not support IEEE-interface yet (and maybe won't ever - not really useful)
- does not support Winchester operation yet, although BIOS ROMs are included
- m68k_cpu.c has a number of not yet implemented instructions (although sufficient for CP/M-68K!)
(implementation in progress)
- does not yet fully support 68010 CPU (in progress, not needed for Sage, though)
- does not implement 68881 FPU (in progress, not needed for Sage, though)
- has stubs for MMU integration, but does not yet implement one - passthrough (in progress, not needed for Sage, though)
- still contains some timing bug in floppy operation (timing loop, 8253 emulation, IRQ speed) which
results in rather long floppy recognition time (disk change), after that I/O is at acceptable speed
- probably there is still a bug in console/sio telnet handling when the character buffer
is full (no automatic draining, will be investigated)
- no optimization of simulation speed at all, but runs acceptable with current PCs.
- not yet tested under anything else than MINGW
Holger Veit, March 2011
$ BIN/sage
Sage-II/IV 68k simulator V3.8-2
sim> show dev
Sage-II/IV 68k simulator configuration
CPU, BIOS=sage-ii.hex
PIC, I/O=0xFFC041-0xFFC043
TIMER1, I/O=0xFFC001-0xFFC007
TIMER2, I/O=0xFFC081-0xFFC087
DIP, I/O=0xFFC021-0xFFC027, GROUPA=11100111, GROUPB=11111000
FD, I/O=0xFFC051-0xFFC053, 2 units
CONS, I/O=0xFFC071-0xFFC073, 2 units
SIO, I/O=0xFFC031-0xFFC033, 2 units
LP, I/O=0xFFC061-0xFFC067
sim> quit
Goodbye
Debug output disabled
$ cp SAGE/FILES/68k.sim .
$ cp SAGE/FILES/cpm68k12.imd .
$ cp SAGE/sage-ii.hex .
$ BIN/sage 68k.sim
Sage-II/IV 68k simulator V3.8-2
Debug output to "debug.log"
Loading boot code from sage-ii.hex
SAGE II Startup Test [1.2]
RAM Size = 512K
Booting from Floppy
SAGE CP/M-68k Bootstrap v2.1
SAGE CP/M-68k v1.2 447K TPA
A>STARTUP
A>SETENV TERM TVI950
A>SETENV PATH |A0:
A>dir
A: MINCE SWP : MINCE 68K : CPM SYS : SAGEBIOS SYS : PIP 68K
A: STAT 68K : AR68 68K : LO68 68K : AS68 68K : MIND SUB
A: DDT 68K : SAGE4UTL 68K : INIT 68K : DUMP 68K : COPY 68K
A: DDT68000 68K : P SUB : ASGO SUB : PE SUB : AS SUB
A: LNK SUB : M SUB : ARMATH SUB : FIND 68K : RED SUB
A: SCREEN 68K : MCC SUB : LINKCORE SUB : SETPRNTR 68K : AS68SYMB DAT
A: E SUB : REDASM SUB : CORE SUB : PRINT 68K : SETENV 68K
A: STARTUP SUB : HALT 68K : SPACE SUB : SIG TXT : SPACEM SUB
A: ORBIT SUB : TLNK SUB : BRWNIES TXT
A>stat a:
A: RW, FREE SPACE: 0K
A>^E
Simulation stopped, PC: 0007C8C4 (stop #2000)
sim>quit
Goodbye
Debug output disabled

62
SAGE/sage_aux.c Normal file
View file

@ -0,0 +1,62 @@
/* sage_aux.c: serial device for sage-II system
Copyright (c) 2009, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
12-Oct-09 HV Initial version
*/
#include "sage_defs.h"
static t_stat sageaux_reset(DEVICE* dptr);
UNIT sageaux_unit[] = {
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) }
};
REG sageaux_reg[] = {
{ NULL }
};
static MTAB sageaux_mod[] = {
{ 0 }
};
DEVICE sageaux_dev = {
"AUX", sageaux_unit, sageaux_reg, sageaux_mod,
4, 16, 32, 2, 16, 16,
NULL, NULL, &sageaux_reset,
NULL, NULL, NULL,
NULL, DEV_DISABLE|DEV_DIS, 0,
NULL, NULL, NULL
};
static t_stat sageaux_reset(DEVICE* dptr)
{
printf("sageaux_reset\n");
return SCPE_OK;
}

464
SAGE/sage_cons.c Normal file
View file

@ -0,0 +1,464 @@
/* sage_sio.c: serial devices for sage-II system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
12-Oct-09 HV Initial version
24-Jul-10 HV Added TMXR code to attach CONS and SIO to network
*/
#include "sim_defs.h"
#include "sim_timer.h"
#include "sage_defs.h"
#include "sim_sock.h"
#include "sim_tmxr.h"
#define SIOPOLL 0
#define SIOTERM 1
#define SIO_POLL_FIRST 1 /* immediate */
#define SIO_POLL_RATE 100 /* sample 100 times /sec */
#define SIO_POLL_WAIT 15800 /* about 10ms */
#define SIO_OUT_WAIT 200
static t_stat sio_reset(DEVICE* dptr);
static t_stat sioterm_svc(UNIT*);
static t_stat siopoll_svc(UNIT*);
static t_stat sio_attach(UNIT*,char*);
static t_stat sio_detach(UNIT*);
static t_stat sio_txint(I8251* chip);
static t_stat sio_rxint(I8251* chip);
extern DEVICE sagesio_dev;
UNIT sio_unit[] = {
{ UDATA (&siopoll_svc, UNIT_ATTABLE, 0), SIO_POLL_WAIT },
{ UDATA (&sioterm_svc, UNIT_IDLE, 0), SIO_OUT_WAIT }
};
static SERMUX sio_mux = {
SIO_POLL_FIRST, /*pollfirst*/
SIO_POLL_RATE, /*pollrate*/
{ 0 }, /*ldsc*/
{ 1, 0, 0, 0 }, /*desc*/
&sio_unit[SIOTERM], /*term_unit*/
&sio_unit[SIOPOLL] /*poll unit*/
};
static I8251 u58 = {
{0,0,U58_ADDR,4,2},
&sagesio_dev,NULL,NULL,i8251_reset,
&sio_txint,&sio_rxint,
&sio_unit[SIOPOLL],&sio_unit[SIOTERM],
&sio_mux
};
REG sio_reg[] = {
{ DRDATA(INIT, u58.init, 3) },
{ HRDATA(MODE, u58.mode, 8) },
{ HRDATA(SYNC1, u58.sync1, 8) },
{ HRDATA(SYNC2, u58.sync2, 8) },
{ HRDATA(CMD, u58.cmd, 8) },
{ HRDATA(IBUF, u58.ibuf, 8) },
{ HRDATA(OBUF, u58.obuf, 8) },
{ HRDATA(STATUS, u58.status, 8) },
{ HRDATA(STATUS, u58.bitmask, 8), REG_HRO },
{ 0 }
};
static MTAB sio_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ 0 }
};
DEVICE sagesio_dev = {
"SIO", sio_unit, sio_reg, sio_mod,
2, 16, 32, 2, 16, 16,
NULL, NULL, &sio_reset,
NULL, &sio_attach, &sio_detach,
&u58, DEV_DEBUG, 0,
i8251_dt, NULL, NULL
};
static t_stat sioterm_svc(UNIT* uptr)
{
DEVICE* dptr = find_dev_from_unit(uptr);
I8251* chip = (I8251*)dptr->ctxt;
SERMUX* mux = chip->mux;
t_stat rc;
int ch = chip->obuf;
/* suppress NUL bytes after CR LF */
switch (ch) {
case 0x0d:
chip->crlf = 1; break;
case 0x0a:
chip->crlf = chip->crlf==1 ? 2 : 0; break;
case 0:
if (chip->crlf==2) goto set_stat;
default:
chip->crlf = 0;
}
/* TODO? sim_tt_outcvt */
/* attached to a telnet port? */
if (mux->poll->flags & UNIT_ATT) {
if ((rc=tmxr_putc_ln(&mux->ldsc, ch & chip->bitmask)) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
return SCPE_OK;
} else
tmxr_poll_tx(&mux->desc);
} else {
/* no, use normal terminal output */
if ((rc=sim_putchar_s(ch & chip->bitmask)) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
return rc==SCPE_STALL ? SCPE_OK : rc;
}
}
set_stat:
chip->status |= I8251_ST_TXEMPTY;
if (chip->cmd & I8251_CMD_TXEN) {
chip->status |= I8251_ST_TXRDY;
return sio_txint(chip);
}
chip->status &= ~I8251_ST_TXRDY;
return SCPE_OK;
}
static t_stat siopoll_svc(UNIT* uptr)
{
int32 c;
DEVICE* dptr = find_dev_from_unit(uptr);
I8251* chip = (I8251*)dptr->ctxt;
SERMUX* mux = chip->mux;
sim_activate(uptr, uptr->wait); /* restart it again */
/* network attached? */
if (mux->poll->flags & UNIT_ATT) {
if (tmxr_poll_conn(&mux->desc) >= 0) /* new connection? */
mux->ldsc.rcve = 1;
tmxr_poll_rx(&mux->desc);
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
/* input ready */
c = tmxr_getc_ln(&mux->ldsc);
if ((c & TMXR_VALID)==0) return SCPE_OK;
c &= 0xff; /* extract character */
} else
return SCPE_OK;
if (!(chip->cmd & I8251_CMD_RXE)) { /* ignore data if receiver not enabled */
chip->status &= ~I8251_ST_RXRDY;
return SCPE_OK;
}
/* got char */
if (c & SCPE_BREAK) { /* a break? */
c = 0;
chip->status |= I8251_ST_SYNBRK;
} else
chip->status &= ~I8251_ST_SYNBRK;
/* TODO? sim_tt_icvt */
chip->ibuf = c & chip->bitmask;
if (chip->status & I8251_ST_RXRDY)
chip->status |= I8251_ST_OE;
chip->status |= I8251_ST_RXRDY;
return sio_rxint(chip);
}
static t_stat sio_reset(DEVICE* dptr)
{
t_stat rc;
I8251* chip = (I8251*)dptr->ctxt;
SERMUX* mux = chip->mux;
if ((rc = (dptr->flags & DEV_DIS) ?
del_iohandler(chip) :
add_iohandler(mux->poll,chip,i8251_io)) != SCPE_OK) return rc;
u58.reset(&u58);
mux->term->wait = 1000; /* TODO adjust to realistic speed */
/* network attached? */
if (mux->poll->flags & UNIT_ATT) {
mux->poll->wait = mux->pfirst;
sim_activate(mux->poll,mux->poll->wait); /* start poll routine */
} else
sim_cancel(mux->poll);
sim_cancel(mux->term);
return SCPE_OK;
}
static t_stat sio_attach(UNIT* uptr, char* cptr)
{
return mux_attach(uptr,cptr,&sio_mux);
}
static t_stat sio_detach(UNIT* uptr)
{
return mux_detach(uptr,&sio_mux);
}
static t_stat sio_txint(I8251* chip)
{
TRACE_PRINT0(DBG_UART_IRQ,"Raise TX Interrupt");
return sage_raiseint(SIOTX_PICINT);
}
static t_stat sio_rxint(I8251* chip)
{
TRACE_PRINT0(DBG_UART_IRQ,"Raise RX Interrupt");
return sage_raiseint(SIORX_PICINT);
}
/***************************************************************************************************/
#define CONSPOLL 0
#define CONSTERM 1
#define CONS_POLL_FIRST 1 /* immediate */
#define CONS_POLL_RATE 100 /* sample 100 times /sec */
#define CONS_POLL_WAIT 15800 /* about 10ms */
#define CONS_OUT_WAIT 200
static t_stat cons_reset(DEVICE* dptr);
static t_stat cons_txint(I8251* chip);
static t_stat cons_rxint(I8251* chip);
static t_stat conspoll_svc(UNIT*);
static t_stat consterm_svc(UNIT*);
static t_stat cons_attach(UNIT*,char*);
static t_stat cons_detach(UNIT*);
extern DEVICE sagecons_dev;
UNIT cons_unit[] = {
{ UDATA (&conspoll_svc, UNIT_ATTABLE, 0), CONS_POLL_WAIT },
{ UDATA (&consterm_svc, UNIT_IDLE, 0), CONS_OUT_WAIT }
};
static SERMUX cons_mux = {
CONS_POLL_FIRST,
CONS_POLL_RATE,
{ 0 },
{ 1, 0, 0, 0 },
&cons_unit[CONSTERM],
&cons_unit[CONSPOLL]
};
static I8251 u57 = {
{ 0,0,U57_ADDR,4,2},
&sagecons_dev,NULL,NULL,&i8251_reset,
&cons_txint,&cons_rxint,
&cons_unit[CONSPOLL],&cons_unit[CONSTERM],
&cons_mux
};
REG cons_reg[] = {
{ DRDATA(INIT, u57.init, 3) },
{ HRDATA(MODE, u57.mode, 8) },
{ HRDATA(SYNC1, u57.sync1, 8) },
{ HRDATA(SYNC2, u57.sync2, 8) },
{ HRDATA(CMD, u57.cmd, 8) },
{ HRDATA(IBUF, u57.ibuf, 8) },
{ HRDATA(OBUF, u57.obuf, 8) },
{ HRDATA(STATUS, u57.status, 8) },
{ HRDATA(BITS, u57.bitmask,8), REG_HRO },
{ 0 }
};
static MTAB cons_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ 0 }
};
DEVICE sagecons_dev = {
"CONS", cons_unit, cons_reg, cons_mod,
2, 16, 32, 2, 16, 16,
NULL, NULL, &cons_reset,
NULL, &cons_attach, &cons_detach,
&u57, DEV_DEBUG, 0,
i8251_dt, NULL, NULL
};
static t_stat cons_reset(DEVICE* dptr)
{
t_stat rc;
int32 wait;
I8251* chip = (I8251*)dptr->ctxt;
SERMUX* mux = chip->mux;
if ((rc = (dptr->flags & DEV_DIS) ?
del_iohandler(chip) :
add_iohandler(mux->poll,chip,&i8251_io)) != SCPE_OK) return rc;
u57.reset(&u57);
/* initialize POLL timer */
wait = mux->poll->wait = CONS_POLL_WAIT;
sim_rtcn_init(wait, TMR_CONS);
u57.oob = TRUE; /* this is the console */
sim_activate(mux->poll, wait);
sim_cancel(mux->term);
return SCPE_OK;
}
/* this service is started when a unit is attached, or characters are available on keyboard */
static t_stat conspoll_svc(UNIT* uptr)
{
int32 c, kbdc;
DEVICE* dptr = find_dev_from_unit(uptr);
I8251* chip = (I8251*)dptr->ctxt;
SERMUX* mux = chip->mux;
uptr->wait = sim_rtcn_calb(mux->prate, TMR_CONS); /* calibrate timer */
sim_activate(uptr, uptr->wait); /* restart it again */
kbdc = sim_poll_kbd(); /* check keyboard */
if (kbdc==SCPE_STOP) return kbdc; /* handle CTRL-E */
/* network-redirected input? */
if (mux->poll->flags & UNIT_ATT) {
if (tmxr_poll_conn(&mux->desc) >= 0) /* incoming connection */
mux->ldsc.rcve = 1;
tmxr_poll_rx(&mux->desc); /* poll for input */
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
/* input ready */
c = tmxr_getc_ln(&mux->ldsc);
if ((c & TMXR_VALID)==0) return SCPE_OK;
c &= 0xff; /* extract character */
} else {
c = kbdc; /* use char polled from keyboard instead */
if (c < SCPE_KFLAG) return c; /* ignore data if not valid */
}
if (!(chip->cmd & I8251_CMD_RXE)) { /* ignore data if receiver not enabled */
chip->status &= ~I8251_ST_RXRDY;
return SCPE_OK;
}
/* got char */
if (c & SCPE_BREAK) { /* a break? */
c = 0;
chip->status |= I8251_ST_SYNBRK;
} else
chip->status &= ~I8251_ST_SYNBRK;
/* TODO? sim_tt_icvt */
chip->ibuf = c & chip->bitmask;
if (chip->status & I8251_ST_RXRDY)
chip->status |= I8251_ST_OE;
chip->status |= I8251_ST_RXRDY;
return cons_rxint(chip);
}
static t_stat consterm_svc(UNIT* uptr)
{
DEVICE* dptr = find_dev_from_unit(uptr);
I8251* chip = (I8251*)dptr->ctxt;
SERMUX* mux = chip->mux;
t_stat rc;
int ch = chip->obuf;
/* suppress NUL bytes after CR LF */
switch (ch) {
case 0x0d:
chip->crlf = 1; break;
case 0x0a:
chip->crlf = (chip->crlf==1) ? 2 : 0; break;
case 0:
if (chip->crlf==2) goto set_stat;
default:
chip->crlf = 0;
}
/* TODO? sim_tt_outcvt */
/* attached to a telnet port? */
if (mux->poll->flags & UNIT_ATT) {
if ((rc=tmxr_putc_ln(&mux->ldsc, ch & chip->bitmask)) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
return SCPE_OK;
} else
tmxr_poll_tx(&mux->desc);
} else {
/* no, use normal terminal output */
if ((rc=sim_putchar_s(ch & chip->bitmask)) != SCPE_OK) {
sim_activate(uptr, uptr->wait);
return rc==SCPE_STALL ? SCPE_OK : rc;
}
}
set_stat:
chip->status |= I8251_ST_TXEMPTY;
if (chip->cmd & I8251_CMD_TXEN) {
chip->status |= I8251_ST_TXRDY;
return cons_txint(chip);
}
chip->status &= ~I8251_ST_TXRDY;
return SCPE_OK;
}
static t_stat cons_txint(I8251* chip)
{
TRACE_PRINT0(DBG_UART_IRQ,"Raise TX Interrupt");
return sage_raiseint(CONSTX_PICINT);
}
static t_stat cons_rxint(I8251* chip)
{
TRACE_PRINT0(DBG_UART_IRQ,"Raise RX Interrupt");
return m68k_raise_autoint(CONSRX_AUTOINT);
}
static t_stat cons_attach(UNIT* uptr,char* cptr)
{
return mux_attach(uptr,cptr,&cons_mux);
}
static t_stat cons_detach(UNIT* uptr)
{
return mux_detach(uptr,&cons_mux);
}
t_stat mux_attach(UNIT* uptr, char* cptr, SERMUX* mux)
{
t_stat rc;
mux->desc.ldsc = &mux->ldsc;
if ((rc = tmxr_attach(&mux->desc, uptr, cptr)) == SCPE_OK) {
mux->poll->wait = mux->pfirst;
sim_activate(mux->poll,mux->poll->wait);
}
return rc;
}
t_stat mux_detach(UNIT* uptr,SERMUX* mux)
{
t_stat rc = tmxr_detach(&mux->desc, uptr);
mux->ldsc.rcve = 0;
sim_cancel(mux->poll);
sim_cancel(mux->term);
return rc;
}

195
SAGE/sage_cpu.c Normal file
View file

@ -0,0 +1,195 @@
/* sage_cpu.c: CPU simulator for sage-II/IV system
Copyright (c) 20092010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#include "sage_defs.h"
static t_stat sagecpu_reset(DEVICE* dptr);
static t_stat sagecpu_boot(int unit,DEVICE* dptr);
static t_stat sage_translateaddr(t_addr in,t_addr* out, IOHANDLER** ioh,int rw,int fc,int dma);
static t_stat sage_mem(t_addr addr,uint8** mem);
static t_stat sagecpu_set_bios(UNIT *uptr, int32 value, char *cptr, void *desc);
static t_stat sagecpu_show_bios(FILE *st, UNIT *uptr, int32 val, void *desc);
static uint8* ROM = 0;
static int rom_enable = TRUE; /* LS74 U51 in CPU schematic */
extern int32 DR[];
extern t_addr AR[];
#define UNIT_CPU_V_BIOS UNIT_CPU_V_FREE /* has custom BIOS */
#define UNIT_CPU_BIOS (1 << UNIT_CPU_V_BIOS)
#define MAX_ROMSIZE 16384
#ifdef SAGE_IV
char* biosfile = "sage-iv.hex";
#else
char* biosfile = "sage-ii.hex";
#endif
static MTAB sagecpu_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "BIOS", "BIOS", &sagecpu_set_bios, &sagecpu_show_bios },
M68KCPU_STDMOD,
{ 0 }
};
UNIT sagecpu_unit = {
UDATA (NULL, UNIT_FIX|UNIT_BINK|CPU_TYPE_68000|UNIT_CPU_EXC|UNIT_CPU_STOP|UNIT_CPU_PRVIO, SAGEMEM)
};
#define DBG_CPU_OSCPM DBG_CPU_CUSTOM1
DEBTAB sagecpu_dt[] = {
{ "EXC", DBG_CPU_EXC },
{ "PC", DBG_CPU_PC },
{ "INT", DBG_CPU_INT },
{ "CTRACE", DBG_CPU_CTRACE },
{ "BTRACE", DBG_CPU_BTRACE },
{ "OSCPM", DBG_CPU_OSCPM },
{ NULL, 0 }
};
DEVICE sagecpu_dev = {
"CPU", &sagecpu_unit, m68kcpu_reg, sagecpu_mod,
1, 16, 32, 2, 16, 16,
&m68kcpu_ex, &m68kcpu_dep, &sagecpu_reset,
&sagecpu_boot, NULL, NULL,
NULL, DEV_DEBUG, 0,
sagecpu_dt, NULL, NULL
};
static t_stat sagecpu_set_bios(UNIT *uptr, int32 value, char *cptr, void *desc)
{
FILE* fp;
if (cptr==NULL) return SCPE_ARG;
if ((fp=fopen(cptr,"r"))==0) return SCPE_OPENERR;
fclose(fp);
biosfile = malloc(strlen(cptr)+1);
strcpy(biosfile,cptr);
/* enforce reload of BIOS code on next boot */
if (ROM != 0) free(ROM);
ROM = 0;
return SCPE_OK;
}
static t_stat sagecpu_show_bios(FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "BIOS=%s", biosfile);
return SCPE_OK;
}
t_stat sagecpu_boot(int32 unitno,DEVICE* dptr)
{
t_stat rc;
if (!ROM) return SCPE_IERR;
if (*ROM==0) {
printf("Loading boot code from %s\n",biosfile);
if ((rc = load_cmd(0,biosfile)) != SCPE_OK) return rc;
}
return m68kcpu_boot(unitno,dptr);
}
/* special logic: capture essential TRAP 8-14 for debugging */
static void sage_trapcallback(DEVICE* dptr,int trapnum)
{
if ((dptr->dctrl & DBG_CPU_OSCPM) && sim_deb) {
if (trapnum>=0x08 && trapnum<=0x0e) {
fprintf(sim_deb,"SAGE: TRAP #%x: D0=%x A0=%x\n",trapnum,DR[0],AR[0]);
}
if (trapnum==2) {
fprintf(sim_deb,"SAGE: CPM BDOS #%d D1=0x%x D2=0x%x\n",DR[0]&0xff,DR[1],DR[2]);
}
if (trapnum==3) {
fprintf(sim_deb,"SAGE: CPM BIOS #%d D1=0x%x D2=0x%x\n",DR[0]&0xff,DR[1],DR[2]);
}
}
}
static t_stat sagecpu_reset(DEVICE* dptr)
{
t_stat rc;
/* set CPU pointers */
m68kcpu_dev = &sagecpu_dev;
m68kcpu_unit = &sagecpu_unit;
/* redefine memory handlers */
TranslateAddr = &sage_translateaddr;
Mem = &sage_mem;
if (!ROM) ROM = (uint8*)calloc(MAX_ROMSIZE,1);
rom_enable = TRUE;
if ((rc=m68kcpu_reset(dptr)) != SCPE_OK) return rc;
/* redirect callbacks */
m68kcpu_trapcallback = &sage_trapcallback;
return SCPE_OK;
}
uint8 ioemul[4] = { 0,0,0,0 };
/* sage memory */
static t_stat sage_mem(t_addr addr,uint8** mem)
{
t_addr a;
// printf("Try to access %x\n",addr); fflush(stdout);
if (rom_enable && addr >= 0 && addr < MAX_ROMSIZE) { /* boot rom mapped to zero page */
*mem = ROM+addr;
return SCPE_OK;
}
a = addr - 0xfe0000; /* boot rom at normal ROM page */
if (a >= 0 && a < MAX_ROMSIZE) {
rom_enable = FALSE;
*mem = ROM+a;
return SCPE_OK;
}
a = addr - 0xffc0fe;
if (a >= 0 && a < 2) { /* boot rom diagnostic address: black hole */
ioemul[0] = ioemul[1] = 0;
*mem = ioemul+a;
return SCPE_OK;
}
a = addr - 0xff0000;
if (a >= 0 && a < 0x10000) {
*mem = ioemul;
return SCPE_OK;
}
if (addr > MEMORYSIZE) return SIM_NOMEM;
return m68k_mem(addr,mem);
}
t_stat sage_translateaddr(t_addr in,t_addr* out, IOHANDLER** ioh,int rw,int fc,int dma)
{
static uint32 bptype[] = { R_BKPT_SPC|SWMASK('R'), W_BKPT_SPC|SWMASK('W') };
t_addr ma = in & addrmask;
if (sim_brk_summ && sim_brk_test(ma, bptype[rw])) return STOP_IBKPT;
return m68k_translateaddr(in,out,ioh,rw,fc,dma);
}

152
SAGE/sage_defs.h Normal file
View file

@ -0,0 +1,152 @@
/* sage_defs.h: simulator header file for sage-II system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
10-Jan-10 HV Defines for certain chip bits/registers
04-Oct-09 HV Initial version
*/
#ifndef SAGE_DEFS_H_
#define SAGE_DEFS_H_
#include "sim_defs.h"
#include "m68k_cpu.h"
/* don't define this yet, won't work */
#undef SAGE_IV
#define UNIT_CPU_V_ROM UNIT_CPU_V_FREE /* has switchable ROM */
#define UNIT_CPU_ROM (1 << UNIT_CPU_V_ROM)
#define SAGEMEM (128*1024)
#define ROMBASE 0xfe0000 /* base address of ROM */
#ifdef SAGE_IV
#define ROMSIZE 0x004000 /* size of ROM (4K words) */
#else
#define ROMSIZE 0x002000 /* size of ROM (4K words) */
#endif
/* simh timers */
#define TMR_RTC1 0
#define TMR_RTC2 1
#define TMR_CONS 2
#define TMR_INT 3
/* definitions for certain chips */
#include "chip_defs.h"
/* PIC base address */
#define U73_ADDR 0xffc041
extern t_stat sage_raiseint(int level); /* sage specific interrupt handler */
/* 8255 for dip switches and floppy control */
#define U22_ADDR 0xffc021
extern uint32 *u22_portc; /* exposed for use by FD device */
#define U22C_FRES 0x80
#define U22C_PCRMP 0x40
#define U22C_MOT 0x20
#define U22C_SL1 0x10
#define U22C_SL0 0x08
#define U22C_FDIE 0x04
#define U22C_RDY 0x02
#define U22C_TC 0x01
/* 8253 timer units */
#define U75_ADDR 0xffc001
#define U74_ADDR 0xffc081
#define TIMER2C0_PICINT 6
#define TIMER2C2_PICINT 0
/* FDC */
#define U21_ADDR 0xffc051
extern I8272 u21;
#define FDC_AUTOINT 6
/* LP port */
#define U39_ADDR 0xffc061
#define LP_PICINT 5
#define SI_PICINT 7
#define U39B_FDI 0x01
#define U39B_WP 0x02
#define U39B_RG 0x04
#define U39B_CD 0x08
#define U39B_BUSY 0x10
#define U39B_PAPER 0x20
#define U39B_SEL 0x40
#define U39B_FAULT 0x80
#define U39C_PRES 0x01
#define U39C_SC 0x02
#define U39C_SI 0x04
#define U39C_LEDR 0x08
#define U39C_STROBE 0x10
#define U39C_PRIME 0x20
#define U39C_RCNI 0x40
#define U39C_RMI 0x80
/* SIO port */
#define U58_ADDR 0xffc031
#define SIORX_PICINT 1
#define SIOTX_PICINT 3
/* CONS port */
#define U57_ADDR 0xffc071
#define CONSRX_AUTOINT 5
#define CONSTX_PICINT 2
/* unimplemented */
#define IEEEBASE 0xffc011 /* IEEE-488 interface (TMS9914) */
/* winchester board: not yet */
#define S2651d 0xffc401 /* aux serial 4 */
#define S2651d_DATA (S2651d+0) /* RW data port aux 4 */
#define S2651d_STATUS (S2651d+2) /* R status aux 4 */
#define S2651d_MODE (S2651d+4) /* W mode aux 4 */
#define S2651d_CTRL (S2651d+6) /* W mode aux 4 */
#define S2651c 0xffc441 /* aux serial 3 */
#define S2651c_DATA (S2651c+0) /* RW data port aux 3 */
#define S2651c_STATUS (S2651c+2) /* R status aux 3 */
#define S2651c_MODE (S2651c+4) /* W mode aux 3 */
#define S2651c_CTRL (S2651c+6) /* W mode aux 3 */
#define S2651b 0xffc481 /* aux serial 2 */
#define S2651b_DATA (S2651b+0) /* RW data port aux 2 */
#define S2651b_STATUS (S2651b+2) /* R status aux 2 */
#define S2651b_MODE (S2651b+4) /* W mode aux 2 */
#define S2651b_CTRL (S2651b+6) /* W mode aux 2 */
#define S2651a 0xff4c1 /* aux serial 1 */
#define S2651a_DATA (S2651a+0) /* RW data port aux 1 */
#define S2651a_STATUS (S2651a+2) /* R status aux 1 */
#define S2651a_MODE (S2651a+4) /* W mode aux 1 */
#define S2651a_CTRL (S2651a+6) /* W mode aux 1 */
/* must be included at the end */
#include "m68k_cpu.h"
#endif

139
SAGE/sage_fd.c Normal file
View file

@ -0,0 +1,139 @@
/* sage_fd.c: Floppy device for sage-II system
Copyright (c) 2009,2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#include "sage_defs.h"
static t_stat sagefd_reset(DEVICE* dptr);
static t_stat sagefd_boot(int32 unit_num,DEVICE* dptr);
static void sagefd_seldrv(I8272* chip,int drvnum);
static void sagefd_interrupt(I8272* chip,int delay);
extern DEVICE sagefd_dev;
static t_stat fdcint_svc(UNIT*);
/* this is the FDC chip */
I8272 u21 = {
{ 0, 0, U21_ADDR, 4, 2 },
&sagefd_dev,
NULL, NULL, &i8272_reset, &sagefd_seldrv, &sagefd_interrupt
};
UNIT sagefd_unit[] = {
{ UDATA (&fdcint_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, I8272_CAPACITY), 58200 },
{ UDATA (&fdcint_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, I8272_CAPACITY), 58200 }
};
REG sagefd_reg[] = {
{ NULL }
};
static MTAB sagefd_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ UNIT_I8272_WLK, 0, "WRTENB", "WRTENB", NULL },
{ UNIT_I8272_WLK, UNIT_I8272_WLK, "WRTLCK", "WRTLCK", NULL },
{ UNIT_I8272_VERBOSE, 0, "QUIET", "QUIET", NULL },
{ UNIT_I8272_VERBOSE, UNIT_I8272_VERBOSE, "VERBOSE", "VERBOSE", NULL },
{ 0 }
};
DEVICE sagefd_dev = {
"FD", sagefd_unit, sagefd_reg, sagefd_mod,
2, 16, 32, 2, 16, 16,
NULL, NULL, &sagefd_reset,
&sagefd_boot, &i8272_attach, &i8272_detach,
&u21, (DEV_DISABLE|DEV_DEBUG), 0,
i8272_dt, NULL, NULL
};
static void sagefd_seldrv(I8272* chip,int drvnum)
{
/* this routine defeats the standard drive select in i8272.c
* which interprets the US0/US1 bits of various commands.
* Sage uses 8255 portc bits for that, and always leaves
* US0/US1 = 0, despite which drive is selected.
* The actual code to select drives is in sage_stddev.c in u22callc()
*/
return;
}
static t_stat sagefd_reset(DEVICE* dptr)
{
t_stat rc;
I8272* chip = (I8272*)dptr->ctxt;
/* fixup device link */
i8272_dev = dptr;
rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
del_iohandler((void*)chip) :
add_iohandler(&sagefd_unit[0],(void*)chip,i8272_io);
if (rc != SCPE_OK) return rc;
return (*chip->reset)(chip);
}
static t_stat fdcint_svc(UNIT* unit)
{
#if DBG_MSG==1
I8272* chip;
DEVICE* dptr;
if (!unit) return -1;
dptr = find_dev_from_unit(unit);
if (!dptr) return -1;
chip = (I8272*)dptr->ctxt;
#endif
if (*u22_portc & U22C_FDIE) {
TRACE_PRINT0(DBG_FD_IRQ,"FDCINT_SVC: deliver interrupt");
m68k_raise_autoint(FDC_AUTOINT);
} else {
TRACE_PRINT0(DBG_FD_IRQ,"FDCINT_SVC: int not granted");
}
return SCPE_OK;
}
static t_stat sagefd_boot(int32 unit_num,DEVICE* dptr)
{
printf("sagefd_boot\n");
return SCPE_OK;
}
static void sagefd_interrupt(I8272* chip,int delay)
{
TRACE_PRINT0(DBG_FD_IRQ,"SAGEFD_INT: request interrupt");
sim_activate(&sagefd_unit[0],delay);
}
/* dummy routines for i8272 - sage does not use DMA */
void PutByteDMA(uint32 addr, uint8 data)
{
}
uint8 GetByteDMA(uint32 addr)
{
return 0;
}

84
SAGE/sage_hd.c Normal file
View file

@ -0,0 +1,84 @@
/* sage_fd.c: Harddisk device for sage-II system
Copyright (c) 2009, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
12-Oct-09 HV Initial version
*/
#include "sage_defs.h"
static t_stat sagehd_reset(DEVICE* dptr);
static t_stat sagehd_boot(int32 unit_num,DEVICE* dptr);
static t_stat sagehd_attach(UNIT* uptr, char* file);
static t_stat sagehd_detach(UNIT* uptr);
UNIT sagehd_unit[] = {
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_ROABLE, 0) },
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) },
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) },
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) }
};
REG sagehd_reg[] = {
{ NULL }
};
/*
static MTAB sagehd_mod[] = {
{ NULL }
};
*/
DEVICE sagehd_dev = {
"HD", sagehd_unit, sagehd_reg, /*sagehd_mod*/NULL,
4, 16, 32, 2, 16, 16,
NULL, NULL, &sagehd_reset,
&sagehd_boot, &sagehd_attach, &sagehd_detach,
NULL, DEV_DISABLE|DEV_DIS, 0,
NULL, NULL, NULL
};
static t_stat sagehd_reset(DEVICE* dptr)
{
printf("sagehd_reset\n");
return SCPE_OK;
}
static t_stat sagehd_boot(int32 unit_num,DEVICE* dptr)
{
printf("sagehd_boot\n");
return SCPE_OK;
}
static t_stat sagehd_attach(UNIT* uptr, char* file)
{
printf("sagehd_attach\n");
return SCPE_OK;
}
static t_stat sagehd_detach(UNIT* uptr)
{
printf("sagehd_detach\n");
return SCPE_OK;
}

62
SAGE/sage_ieee.c Normal file
View file

@ -0,0 +1,62 @@
/* sage_ieee.c: IEEE 488 device for Sage-II-system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
12-Oct-09 HV Initial version
*/
/* N O T Y E T I M P L E M E N T E D ! ! ! */
#include "sage_defs.h"
#if 0
static t_stat sageieee_reset(DEVICE* dptr);
UNIT sageieee_unit = {
UDATA (NULL, UNIT_FIX | UNIT_BINK, 0)
};
REG sageieee_reg[] = {
{ NULL }
};
static MTAB sageieee_mod[] = {
{ 0 }
};
DEVICE sageieee_dev = {
"IEEE", &sageieee_unit, sageieee_reg, sageieee_mod,
1, 16, 32, 2, 16, 16,
NULL, NULL, &sageieee_reset,
NULL, NULL, NULL,
NULL, DEV_DISABLE|DEV_DIS, 0,
NULL, NULL, NULL
};
static t_stat sageieee_reset(DEVICE* dptr)
{
printf("sageieee_reset\n");
return SCPE_OK;
}
#endif

247
SAGE/sage_lp.c Normal file
View file

@ -0,0 +1,247 @@
/* sage_lp.c: Printer device for sage-II system
Copyright (c) 2009, Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#include "sage_defs.h"
#define UNIT_V_OFFLINE (UNIT_V_UF + 0) /* unit offline */
#define UNIT_OFFLINE (1 << UNIT_V_OFFLINE)
static t_stat sagelp_reset(DEVICE* dptr);
static t_stat sagelp_attach(UNIT *uptr, char *cptr);
static t_stat sagelp_detach(UNIT *uptr);
static t_stat sagelp_output(UNIT *uptr);
static t_stat u39_reset(I8255* chip);
static t_stat u39_calla(I8255* chip,int rw);
static t_stat u39_callb(I8255* chip,int rw);
static t_stat u39_callc(I8255* chip,int rw);
static t_stat u39_ckmode(I8255* chip,uint32 data);
extern DEVICE sagelp_dev;
/* The LP Centronics device in sage is implemented by a 8255 with the following settings:
* port A output data
* port B input status from printer, and from misc devices
* B0 Floppy interrupt flag
* B1 Floppy write protect flag
* B2 Modem ringing indicator
* B3 Modem carrier detect
* B4 Printer BUSY flag
* B5 Printer PAPER flag
* B6 Printer SELECT flag (on/offline)
* B7 Printer FAULT flag
* port C lower half output control for misc devices
* C0 Parity error reset
* C1 IEEE enable
* C2 Interrupt level 7
* C3 activity LED
* port C upper half input status from printers
* C4 printer STROBE flag
* C5 printer PRIME flag
* C6 printer ACK INT clear
* C7 modem Ringing/Carrier INT clear (MI)
*/
static I8255 u39 = {
{ 0,0,U39_ADDR,8,2},
&sagelp_dev,
i8255_write,i8255_read,u39_reset,u39_calla,u39_callb,u39_callc,u39_ckmode
};
UNIT sagelp_unit = {
UDATA (NULL, UNIT_SEQ|UNIT_ATTABLE|UNIT_TEXT, 0), SERIAL_OUT_WAIT
};
REG sagelp_reg[] = {
{ HRDATA(PORTA, u39.porta, 8) },
{ HRDATA(PORTB, u39.portb, 8) },
{ HRDATA(PORTC, u39.portc, 8) },
{ HRDATA(CTRL, u39.ctrl, 8) },
{ GRDATA (BUF, sagelp_unit.buf, 16, 8, 0) },
{ DRDATA (POS, sagelp_unit.pos, T_ADDR_W), PV_LEFT },
{ NULL }
};
static MTAB sagelp_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", NULL },
{ UNIT_OFFLINE, 0, "online", "ONLINE", NULL },
{ 0 }
};
DEBTAB sagelp_dt[] = {
{ "WRA", DBG_PP_WRA },
{ "RDB", DBG_PP_RDB },
{ "RDC", DBG_PP_RDC },
{ "WRC", DBG_PP_WRC },
{ "WRMODE", DBG_PP_MODE },
{ NULL, 0 }
};
DEVICE sagelp_dev = {
"LP", &sagelp_unit, sagelp_reg, sagelp_mod,
1, 16, 32, 2, 16, 16,
NULL, NULL, &sagelp_reset,
NULL, &sagelp_attach, &sagelp_detach,
&u39, (DEV_DISABLE|DEV_DEBUG), 0,
sagelp_dt, NULL, NULL
};
t_stat sagelp_reset(DEVICE* dptr)
{
t_stat rc;
if ((rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
del_iohandler(dptr->ctxt) :
add_iohandler(&sagelp_unit,dptr->ctxt,i8255_io)) != SCPE_OK) return rc;
return u39.reset(&u39);
}
/* we don't accept any mode and combination that a 8255 can do, because
* u39 is hardwired to porta=output, portb=input and portc=output
*/
static t_stat u39_calla(I8255* chip, int rw)
{
if (rw) {
sagelp_unit.buf = chip->porta;
TRACE_PRINT1(DBG_PP_WRA,"WR PortA = 0x%x",chip->porta);
}
return SCPE_OK;
}
static t_stat u39_callb(I8255* chip, int rw)
{
if (rw==0) { /* only when reading port */
/* propagate FDC Write Protect */
int portb = 0;
I8272_DRIVE_INFO* dip = &u21.drive[u21.fdc_curdrv];
if (dip->uptr && (dip->uptr->flags & UNIT_I8272_WLK)) {
portb |= U39B_WP;
TRACE_PRINT1(DBG_PP_RDB,"RD PortB: WP+=%d",(portb&U39B_WP)?1:0);
}
/* propagate FDC interrupt */
if (u21.irqflag) {
portb |= U39B_FDI;
TRACE_PRINT0(DBG_PP_RDB,"RD PortB: FDI+=1");
} else {
TRACE_PRINT0(DBG_PP_RDB,"RD PortB: FDI+=0");
}
chip->portb = portb;
}
return SCPE_OK;
}
static t_stat u39_callc(I8255* chip,int rw)
{
if (rw==1) {
if (I8255_FALLEDGE(portc,U39C_STROBE)) {
sagelp_output(&sagelp_unit);
TRACE_PRINT1(DBG_PP_RDC,"RD PortC: STROBE-=%d",chip->portc&U39C_STROBE?1:0);
}
if (I8255_RISEEDGE(portc,U39C_SI)) {
/* printf("rising edge on SI: PC=%x!\n",PCX);*/
TRACE_PRINT1(DBG_PP_RDC,"RD PortC: SI+=%d",chip->portc&U39C_SI?1:0);
sage_raiseint(SI_PICINT);
}
}
return SCPE_OK;
}
static t_stat u39_ckmode(I8255* chip,uint32 data)
{
TRACE_PRINT1(DBG_PP_MODE,"WR Mode: 0x%x",data);
/* BIOS initializes port A as input, later LP is initialized to output */
if (!(data==0x82 || data==0x92)) {
/* hardwired:
* d7=1 -- mode set flag
* d6=0 -+ group a mode 0: basic I/O
* d5=0 -+
* d4=0 -- port a = output / input
* d3=0 -- port c upper = output
* d2=0 -- group b mode 0: basic I/O
* d1=1 -- port b = input
* d0=0 -- port c lower = output
*/
printf("u39_ckmode: unsupported ctrl=0x%02x\n",data);
return STOP_IMPL;
}
chip->portc = 0; /* reset port */
return SCPE_OK;
}
static t_stat u39_reset(I8255* chip)
{
sagelp_unit.buf = 0;
sim_cancel (&sagelp_unit);
return SCPE_OK;
}
static t_stat sagelp_attach (UNIT *uptr, char *cptr)
{
t_stat rc;
rc = attach_unit(uptr, cptr);
if ((sagelp_unit.flags & UNIT_ATT) == 0)
u39.portb |= U39B_PAPER; /* no paper */
return rc;
}
static t_stat sagelp_detach (UNIT *uptr)
{
u39.portb |= U39B_PAPER; /* no paper */
return detach_unit (uptr);
}
static t_stat sagelp_output(UNIT *uptr)
{
if ((uptr->flags & UNIT_ATT)==0) {
u39.portb |= U39B_PAPER; /* unattached means: no paper */
return SCPE_UNATT;
} else if (uptr->flags & UNIT_OFFLINE) {
u39.portb &= ~U39B_SEL; /* offline means: SEL = 0 */
return STOP_OFFLINE;
}
u39.portb &= ~U39B_PAPER; /* has paper */
u39.portb |= U39B_SEL; /* is online */
u39.portb |= U39B_FAULT; /* no fault */
u39.portb &= ~U39B_BUSY; /* not busy */
if ((u39.portc & U39C_STROBE)==0) { /* strobe presented */
fputc (uptr->buf & 0177, uptr->fileref); /* put out char */
if (ferror (uptr->fileref)) {
perror ("LP I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
sagelp_unit.pos = ftell(uptr->fileref); /* update pos */
u39.portc |= U39C_STROBE; /* XXX reset strobe directly */
sage_raiseint(LP_PICINT);
return SCPE_OK;
}
return SCPE_OK;
}

633
SAGE/sage_stddev.c Normal file
View file

@ -0,0 +1,633 @@
/* sage_stddev.c: Standard devices for sage-II system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#include "sim_defs.h"
#include "m68k_cpu.h"
#include "sage_defs.h"
/***********************************************************************************
* 8259-5 interrupt controller
*
* IRQ output hardwired to Interrupt Priority Level 1 in the Sage
* Level 2: from external bus (wired to HDC board, AUX devices)
* Level 3: from external bus
* Level 4: IEEE 488 Interrupt U6
* Level 5: Console Uart U67 Receiver Interrupt
* Level 6: FDI floppy controller
* Level 7: nonmaskable RAM parity error (not possible in simh)
*
* hardwired inputs:
* IR0 = Output 2 of U74 real time clock
* IR1 = Modem Uart U58 Receiver Interrupt
* IR2 = Console Uart U67 Transmitter Interrupt
* IR3 = Modem Uart U58 Receiver Interrupt
* IR4 = Modem Carrier Detect Interrupt U38
* IR5 = LP Port Acknowledge U39/U38
* IR6 = Output 0 of U74 real time clock
* IR7 = Output C2 of U39
*
* Notes:
* INTA- is hardwired to VCC, so vectoring is not possible
* SP- is hardwired to VCC, so buffered mode is not possible, and device is a master.
* CAS0-2 lines are open, no need to handle
* UCSD bios and boot prom do not program the PIC for rotating priorities,
* so effectively prio is always 7.
*
**********************************************************************************/
extern DEVICE sagepic_dev;
static t_stat sagepic_reset(DEVICE* dptr);
static I8259 u73 = { {0,0,U73_ADDR,4,2},
&sagepic_dev,NULL,NULL,i8259_reset
};
UNIT sagepic_unit = {
UDATA (NULL, UNIT_IDLE, 0)
};
REG sagepic_reg[] = {
{ DRDATA(STATE, u73.state, 8) },
{ HRDATA(IRR, u73.irr, 8) },
{ HRDATA(IMR, u73.imr, 8) },
{ HRDATA(ISR, u73.isr, 8) },
{ HRDATA(ICW1, u73.icw1, 8) },
{ HRDATA(ICW2, u73.icw2, 8) },
{ HRDATA(ICW4, u73.icw4, 8) },
{ HRDATA(OCW2, u73.prio, 3) },
{ NULL }
};
static MTAB sagepic_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ 0 }
};
DEVICE sagepic_dev = {
"PIC", &sagepic_unit, sagepic_reg, sagepic_mod,
1, 16, 32, 2, 16, 16,
NULL, NULL, &sagepic_reset,
NULL, NULL, NULL,
&u73, DEV_DEBUG, 0,
i8259_dt, NULL, NULL
};
static t_stat sagepic_reset(DEVICE* dptr)
{
t_stat rc;
if ((rc = (dptr->flags & DEV_DIS) ?
del_iohandler(dptr->ctxt) :
add_iohandler(&sagepic_unit,dptr->ctxt,i8259_io)) != SCPE_OK) return rc;
return u73.reset(&u73);
}
t_stat sage_raiseint(int level)
{
return i8259_raiseint(&u73,level);
}
/******************************************************************************************************
* DIP switches at the back panel.
*
* In the technical manual, switches are layed out 12345678 left to right,
* but here seen as two HEX digits 8765 4321, i.e. 0xc0 is bit 8 and bit 7 set on
*
* a "d" (down) means switch is off or "0", and a "u" (up) means switch is on or "1"
*
* Note that programatically dip switches are port a and b of the onboard 8255 U22
* which also through port c serves part of the FDC signals
*
* group-a:
* 8 7 6 5 4 3 2 1
* | | | | | d d d--- 19,2K baud
* | | | | | d d u--- 9600 baud
* | | | | | d u d--- 4800 baud
* | | | | | d u u--- 2400 baud
* | | | | | u d d--- 1200 baud
* | | | | | u d u--- 600 baud
* | | | | | u u d--- 300 baud
* | | | | | u u u--- reserved
* | | | | d--------- even parity
* | | | | u--------- parity disabled
* | | d d----------- boot to debugger
* | | d u----------- boot to floppy 0
* | | u d----------- boot to harddisk 0 partition 0
* | | u u----------- reserved
* | d--------------- 96 tpi drive
* | u--------------- 48 tpi drive
* x----------------- reserved
*
* group-b:
* 8 7 6 5 4 3 2 1
* | | | +-+-+-+-+--- device talk and listen address
* | | u------------- enable talk
* | | d------------- disable talk
* | u--------------- enable listen
* | d--------------- disable listen
* u----------------- 2 consecutive addresses
* d----------------- 1 address
*/
#if defined(SAGE_IV)
uint32 groupa = 0xd7; /* used by cons device, 19k2, no parity, boot floppy 0 */
uint32 groupb = 0xf8; /* used by ieee device */
#else
uint32 groupa = 0xe7; /* used by cons device, 19k2, no parity, boot winchester 0 */
uint32 groupb = 0xf8; /* used by ieee device */
#endif
static t_stat sagedip_reset(DEVICE* dptr);
static t_stat set_groupa(UNIT *uptr, int32 val, char *cptr, void *desc);
static t_stat show_groupa(FILE *st, UNIT *uptr, int32 val, void *desc);
static t_stat set_groupb(UNIT *uptr, int32 val, char *cptr, void *desc);
static t_stat show_groupb(FILE *st, UNIT *uptr, int32 val, void *desc);
static t_stat u22_reset(I8255* chip);
static t_stat u22_calla(I8255* chip,int rw);
static t_stat u22_callb(I8255* chip,int rw);
static t_stat u22_callc(I8255* chip,int rw);
static t_stat u22_ckmode(I8255* chip,uint32 data);
extern DEVICE sagedip_dev;
static I8255 u22 = {
{ 0,0,U22_ADDR,8,2 },
&sagedip_dev,i8255_write,i8255_read,u22_reset,u22_calla,u22_callb,u22_callc,u22_ckmode
};
uint32* u22_portc = &u22.portc; /* this is used in the FD device as well, but whole 8255 is handled here */
UNIT sagedip_unit = {
UDATA (NULL, UNIT_IDLE, 0)
};
REG sagedip_reg[] = {
{ HRDATA(PORTA, u22.porta, 8) },
{ HRDATA(PORTB, u22.portb, 8) },
{ HRDATA(PORTC, u22.portc, 8) },
{ HRDATA(CTRL, u22.ctrl, 8) },
{ NULL }
};
static MTAB sagedip_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "GROUPA", "GROUPA", &set_groupa, &show_groupa, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "GROUPB", "GROUPB", &set_groupb, &show_groupb, NULL },
{ 0 }
};
/* Debug Flags */
DEBTAB sagedip_dt[] = {
{ "RDA", DBG_PP_RDA },
{ "RDB", DBG_PP_RDB },
{ "WRC", DBG_PP_WRC },
{ "WRMODE", DBG_PP_MODE },
{ NULL, 0 }
};
DEVICE sagedip_dev = {
"DIP", &sagedip_unit, sagedip_reg, sagedip_mod,
1, 16, 32, 2, 16, 16,
NULL, NULL, &sagedip_reset,
NULL, NULL, NULL,
&u22, DEV_DEBUG, 0,
sagedip_dt, NULL, NULL
};
static t_stat sagedip_reset(DEVICE* dptr)
{
t_stat rc;
if ((rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
del_iohandler(dptr->ctxt) :
add_iohandler(&sagedip_unit,dptr->ctxt,i8255_io)) != SCPE_OK) return rc;
/* clear 8255 ctrl register */
return u22.reset(&u22);
}
static t_stat set_gr(char* cptr, uint32* sw)
{
int i;
char c;
if (!cptr) return SCPE_ARG;
*sw = 0;
for (i=0; *cptr && i<8; i++) {
c = *cptr++;
*sw <<= 1;
if (c=='1') *sw |= 1;
else if (c=='0') continue;
else if (c==0) break;
else return SCPE_ARG;
}
return SCPE_OK;
}
static t_stat set_groupa(UNIT *uptr, int32 val, char *cptr, void *desc)
{
return set_gr(cptr,&groupa);
}
static t_stat set_groupb(UNIT *uptr, int32 val, char *cptr, void *desc)
{
return set_gr(cptr,&groupb);
}
static t_stat show_gr(FILE* st, char* prefix, uint32 gr)
{
int i;
fputs(prefix, st);
for (i = 0x80; i > 0; i = i >> 1)
fprintf(st,"%c", gr&i ? '1' : '0');
return SCPE_OK;
}
static t_stat show_groupa(FILE *st, UNIT *uptr, int32 val, void *desc)
{
return show_gr(st, "GROUPA=", groupa);
}
static t_stat show_groupb(FILE *st, UNIT *uptr, int32 val, void *desc)
{
return show_gr(st, "GROUPB=", groupb);
}
static t_stat u22_reset(I8255* chip)
{
chip->ctrl = 0;
chip->portc = 0;
return SCPE_OK;
}
extern I8272 u21;
static t_stat u22_calla(I8255* chip,int rw)
{
if (rw==0) {
chip->porta = groupa & 0xff;
TRACE_PRINT1(DBG_PP_RDA,"WR PortA: 0x%x",groupa);
}
return SCPE_OK;
}
static t_stat u22_callb(I8255* chip,int rw)
{
if (rw==0) {
chip->portb = groupb & 0xff;
TRACE_PRINT1(DBG_PP_RDA,"WR PortB: 0x%x",groupb);
}
return SCPE_OK;
}
/* callback handler for FDC bits */
static t_stat u22_callc(I8255* chip,int rw)
{
/* bit0: TC+ positive enforce that internal data counter of FDC is reset
* bit1: RDY+ positive enable the FDC
* bit2: FDIE+ positive enable FDC interrupt (handled directly by reading portc in sage_fd.c)
* bit3: SL0- negative select of drive 0
* bit4: SL1- negative select of drive 1
* bit5: MOT- negative switch on drive motor (ignored)
* bit6: PCRMP- negative precompensation (ignored)
* bit7: FRES+ positive FDC reset
*/
if (I8255_ISSET(portc,U22C_TC)) { /* TC+ */
i8272_finish(&u21); /* terminate a read/write in progress */
}
if (I8255_ISCLR(portc,U22C_RDY)) { /* RDY+ */
i8272_abortio(&u21); /* abort current op */
}
if (I8255_ISCLR(portc,U22C_SL0)) { /* SL0- */
u21.fdc_curdrv = 0;
} else if (I8255_ISCLR(portc,U22C_SL1)) { /* SL1- */
u21.fdc_curdrv = 1;
} else if (I8255_ISSET(portc,U22C_SL0|U22C_SL1)) { /* deselect drives */
u21.fdc_curdrv = 0;
}
if (I8255_ISSET(portc,U22C_FRES)) { /* FRES+ */
i8272_reset(&u21);
}
TRACE_PRINT(DBG_PP_WRC,(sim_deb,"PORTC Flags: %s%s%s%s%s%s%s%s",
I8255_ISSET(portc,U22C_TC)?"TC ":"",
I8255_ISSET(portc,U22C_RDY)?"RDY ":"",
I8255_ISSET(portc,U22C_FDIE)?"FDIE ":"",
I8255_ISSET(portc,U22C_SL0)?"":"SL0 ",
I8255_ISSET(portc,U22C_SL1)?"":"SL1 ",
I8255_ISSET(portc,U22C_MOT)?"":"MOT ",
I8255_ISSET(portc,U22C_PCRMP)?"":"PCRMP ",
I8255_ISSET(portc,U22C_FRES)?"FRES ":""));
return SCPE_OK;
}
static t_stat u22_ckmode(I8255* chip, uint32 data)
{
/* hardwired:
* d7=1 -- mode set flag
* d6=0 -+ group a mode 0: basic I/O
* d5=0 -+
* d4=1 -- porta = input
* d3=0 -- portc upper = output
* d2=0 -- group b mode 0: basic I/O
* d1=1 -- portb = input
* d0=0 -- portc lower = output
*/
TRACE_PRINT1(DBG_PP_MODE,"WR Mode: 0x%x",data);
if (data != 0x92) {
printf("u22_ckmode: unsupported ctrl=0x%02x\n",data);
return STOP_IMPL;
}
return SCPE_OK;
}
/***********************************************************************************
* Two 8553 timers U75 (TIMER1) and U74 (TIMER2)
* Each contain three 8/16 bit timers
* In the sage hardwired in the following way:
*
* +---------+
* 615kHz--+->|Timer1 C1|---> Baud ser0
* | +---------+
* +->|Timer1 C2|---> Baud ser1
* +---------+
* +---------+ +---------+
* 64kHz---+->|Timer1 C0|--->|Timer2 C0|--> PIC IR6
* | |div 64000| |mode0 |
* | +---------+ +---------+
* | +---------+ +---------+
* +->|Timer2 C1|--->|Timer2 C2|--> PIC IR0
* | | | |
* +---------+ +---------+
*
* NOT UNITS: Timer1 C1 and C2 are programmed in mode 2 as clock dividers for the USARTs
* In this emulation we allow programming them, but since they don't produce interrupts,
* their work is ignored.
*
* Timer1 C0 and timer2 C0 form a clock divider which produces an interrupt at PIC level 6
* Likewise, timer2 C1 and timer2 C2 form a clock divider which produces an interrupt at PIC level 0
*
* Typically, the first one in cascade is programmed in mode 2, the second one in mode 0.
* Timer1 C0 is explicitly programmed as a divider by 64k, so that it feeds timer2 C0
* with a 1Hz clock.
*
* The way the timers are hardwired makes certain mode settings impossible: all GATE
* inputs are set to VCC, so MODE1 and MODE5 are impossible, and MODE4 becomes a
* variant of MODE0. MODE3 is used by the baudrate generators. The timers may run in
* 8 bit mode, but analysis of existing BIOS code (BOOT PROM and UCSD BIOS) uncovered
* they are used in 16 bit mode only.
* So, this implementation only contains the most likely usages, and the other ones have
* to be added when there is a necessity.
*
* Notes on actual implementation:
* Since we know the input clocks, we have just to take care about the division factors
* stored in T1C0 and T2C1. Whenever one of these timers are read out, the actual count
* has to be calculated on the fly. The actual cnt registers only hold the count factors
* programmed, but are never counted down, as, in the case of the 64kHz clock this would
* mean to trigger sim_* events 64000 times a second.
*
***********************************************************************************/
/************************************************************************************
* timer 1
***********************************************************************************/
static t_stat sagetimer1_reset(DEVICE* dptr);
static t_stat timer1_svc(UNIT* uptr);
static t_stat u75_ckmode(I8253* chip, uint32 data);
static t_stat u75_call0(I8253* chip,int addr, uint32* value);
static t_stat sagetimer2_reset(DEVICE* dptr);
static t_stat timer2_svc(UNIT* uptr);
static t_stat u74_ckmode(I8253* chip, uint32 data);
static t_stat u74_call1(I8253* chip,int addr, uint32* value);
extern DEVICE sagetimer1_dev;
extern DEVICE sagetimer2_dev;
/* forward timer 2 */
UNIT sagetimer2_unit = {
UDATA (&timer2_svc, UNIT_IDLE, 0)
};
static I8253 u74 = { {0,0,U74_ADDR,8,2},
&sagetimer2_dev,&sagetimer2_unit,i8253_reset,u74_ckmode,
{ { 0, }, { u74_call1, }, { 0, } }
};
/* timer 1 */
UNIT sagetimer1_unit = {
UDATA (&timer1_svc, UNIT_IDLE, 1)
};
static I8253 u75 = { {0,0,U75_ADDR,8,2},
&sagetimer1_dev,&sagetimer1_unit,i8253_reset,u75_ckmode,
{ { u75_call0, }, { 0, }, { 0, } }
};
REG sagetimer1_reg[] = {
{ HRDATA(INIT, u75.init, 8), REG_HRO },
{ HRDATA(STATE0,u75.cntr[0].state, 8),REG_HRO },
{ HRDATA(STATE1,u75.cntr[1].state, 8),REG_HRO },
{ HRDATA(STATE2,u75.cntr[2].state, 8),REG_HRO },
{ HRDATA(MODE0, u75.cntr[0].mode, 8) },
{ HRDATA(MODE1, u75.cntr[1].mode, 8) },
{ HRDATA(MODE2, u75.cntr[2].mode, 8) },
{ HRDATA(CNT0, u75.cntr[0].count, 16) },
{ HRDATA(CNT1, u75.cntr[1].count, 16) },
{ HRDATA(CNT2, u75.cntr[2].count, 16) },
{ HRDATA(LATCH0,u75.cntr[0].latch, 16) },
{ HRDATA(LATCH1,u75.cntr[1].latch, 16) },
{ HRDATA(LATCH2,u75.cntr[2].latch, 16) },
{ HRDATA(DIV0, u75.cntr[0].divider, 16),REG_HRO },
{ HRDATA(DIV1, u75.cntr[1].divider, 16),REG_HRO },
{ HRDATA(DIV2, u75.cntr[2].divider, 16),REG_HRO },
{ NULL }
};
static MTAB sagetimer1_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ 0 }
};
DEVICE sagetimer1_dev = {
"TIMER1", &sagetimer1_unit, sagetimer1_reg, sagetimer1_mod,
1, 16, 32, 2, 16, 16,
NULL, NULL, &sagetimer1_reset,
NULL, NULL, NULL,
&u75, DEV_DEBUG, 0,
i8253_dt, NULL, NULL
};
static t_stat sagetimer1_reset(DEVICE* dptr)
{
t_stat rc;
if (!(rc = (dptr->flags & DEV_DIS) ?
del_iohandler(dptr->ctxt) :
add_iohandler(&sagetimer1_unit,dptr->ctxt,i8253_io)) != SCPE_OK) return rc;
return u75.reset(&u75);
}
static t_stat timer1_svc(UNIT* uptr)
{
int32 wait;
I8253CNTR* t1c0 = &u75.cntr[0];
I8253CNTR* t2c0 = &u74.cntr[0];
// fprintf(sim_deb,"TIMER1: timer1_svc called T1C0=%d T2C0=%d\n",t1c0->count,t2c0->count);
/* we call this service 64000 times a second to decrement counter T1C0.
* When T1C0 reaches 0, it will decrement T2C0 */
t1c0->count--;
if (t1c0->count <= 0) {
/* reload from divider */
t1c0->count = t1c0->divider;
/* decrement T2C0 counter and raise interrupt 6 if counter is zero */
if (t2c0->count == 0) {
sage_raiseint(TIMER2C0_PICINT);
// printf("timer1 heartbeat\n");
t2c0->count = 65536;
}
t2c0->count--;
}
/* adjust timing */
wait = sim_rtcn_calb(64000,TMR_RTC1);
sim_activate(u75.unit,wait); /* 64000 ticks per second */
return SCPE_OK;
}
static t_stat u75_ckmode(I8253* chip,uint32 mode)
{
/* @TODO check valid modes */
return SCPE_OK;
}
static t_stat u75_call0(I8253* chip,int rw,uint32* value)
{
if (rw==1) {
I8253CNTR* cntr = &chip->cntr[0];
if ((cntr->mode & I8253_BOTH) && (cntr->state & I8253_ST_MSBNEXT)) {
sim_cancel(chip->unit);
return SCPE_OK; /* not fully loaded yet */
} else {
/* start the CK0 clock at 64000Hz */
sim_activate(chip->unit,sim_rtcn_init(64000,TMR_RTC1)); /* use timer1 C0 for this clock */
}
}
return SCPE_OK;
}
/************************************************************************************
* timer 2
***********************************************************************************/
REG sagetimer2_reg[] = {
{ HRDATA(INIT, u74.init, 8), REG_HRO },
{ HRDATA(STATE0,u74.cntr[0].state, 8),REG_HRO },
{ HRDATA(STATE1,u74.cntr[1].state, 8),REG_HRO },
{ HRDATA(STATE2,u74.cntr[2].state, 8),REG_HRO },
{ HRDATA(MODE0, u74.cntr[0].mode, 8) },
{ HRDATA(MODE1, u74.cntr[1].mode, 8) },
{ HRDATA(MODE2, u74.cntr[2].mode, 8) },
{ HRDATA(CNT0, u74.cntr[0].count, 16) },
{ HRDATA(CNT1, u74.cntr[1].count, 16) },
{ HRDATA(CNT2, u74.cntr[2].count, 16) },
{ HRDATA(LATCH0,u74.cntr[0].latch, 16) },
{ HRDATA(LATCH1,u74.cntr[1].latch, 16) },
{ HRDATA(LATCH2,u74.cntr[2].latch, 16) },
{ HRDATA(DIV0, u74.cntr[0].divider, 16),REG_HRO },
{ HRDATA(DIV1, u74.cntr[1].divider, 16),REG_HRO },
{ HRDATA(DIV2, u74.cntr[2].divider, 16),REG_HRO },
{ NULL }
};
static MTAB sagetimer2_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
{ 0 }
};
DEVICE sagetimer2_dev = {
"TIMER2", &sagetimer2_unit, sagetimer2_reg, sagetimer2_mod,
1, 16, 32, 2, 16, 16,
NULL, NULL, &sagetimer2_reset,
NULL, NULL, NULL,
&u74, DEV_DEBUG, 0,
i8253_dt, NULL, NULL
};
static t_stat sagetimer2_reset(DEVICE* dptr)
{
t_stat rc;
if ((rc = (dptr->flags & DEV_DIS) ?
del_iohandler(dptr->ctxt) :
add_iohandler(&sagetimer2_unit,dptr->ctxt,i8253_io)) != SCPE_OK) return rc;
return u74.reset(&u74);
}
static t_stat u74_ckmode(I8253* chip,uint32 mode)
{
/* @TODO check valid modes */
return SCPE_OK;
}
static t_stat u74_call1(I8253* chip,int rw,uint32* value)
{
if (rw==1) {
I8253CNTR* cntr = &chip->cntr[1];
if ((cntr->mode & I8253_BOTH) && (cntr->state & I8253_ST_MSBNEXT)) {
sim_cancel(chip->unit);
return SCPE_OK; /* not fully loaded yet */
} else {
/* start the CK0 clock at 64000Hz */
sim_activate(chip->unit,sim_rtcn_init(64000,TMR_RTC1)); /* use timer1 C0 for this clock */
}
}
return SCPE_OK;
}
static t_stat timer2_svc(UNIT* uptr)
{
int32 wait;
I8253CNTR* t2c1 = &u74.cntr[1];
I8253CNTR* t2c2 = &u74.cntr[2];
/* we call this service 64000 times a second to decrement counter T2C1.
* When T2C1 reaches 0, it will decrement T2C2 */
t2c1->count--;
if (t2c1->count <= 0) {
/* reload from divider */
t2c1->count = t2c1->divider;
/* decrement T2C2 counter and raise interrupt 0 if counter is zero */
if (t2c2->count == 0) {
// printf("timer2 heartbeat\n");
sage_raiseint(TIMER2C2_PICINT);
}
t2c2->count--;
}
/* adjust timing */
wait = sim_rtcn_calb(64000,TMR_RTC1);
sim_activate(u74.unit,wait); /* 64000 ticks per second */
return SCPE_OK;
}

71
SAGE/sage_sys.c Normal file
View file

@ -0,0 +1,71 @@
/* sage_sys.c: SYS definitions for sage-II system
Copyright (c) 2009-2010 Holger Veit
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Holger Veit et al shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Holger Veit et al.
04-Oct-09 HV Initial version
*/
#include <ctype.h>
#include "sage_defs.h"
extern DEVICE sagecpu_dev;
extern DEVICE sagepic_dev;
extern DEVICE sagetimer1_dev;
extern DEVICE sagetimer2_dev;
extern DEVICE sagedip_dev;
extern DEVICE sagefd_dev;
extern DEVICE sagecons_dev;
extern DEVICE sagesio_dev;
extern DEVICE sagelp_dev;
#if 0
extern DEVICE sageieee_dev;
#endif
#ifdef SAGE_IV
extern DEVICE sagehd_dev;
extern DEVICE sageaux_dev;
#endif
char sim_name[] = "Sage-II/IV 68k";
REG *sim_PC = &m68kcpu_reg[18];
int sim_emax = SIM_EMAX;
DEVICE *sim_devices[] = {
&sagecpu_dev,
&sagepic_dev,
&sagetimer1_dev,
&sagetimer2_dev,
&sagedip_dev,
&sagefd_dev,
&sagecons_dev,
&sagesio_dev,
&sagelp_dev,
#if 0
&sageieee_dev,
#endif
#ifdef SAGE_IV
&sagehd_dev,
&sageaux_dev,
#endif
NULL
};

View file

@ -0,0 +1,322 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="PDQ3"
ProjectGUID="{D4F5761A-B543-40ED-9892-12A0255C2B6D}"
RootNamespace="PDQ3"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\PDQ3\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../"
PreprocessorDefinitions="USE_SIM_IMD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib"
OutputFile="$(OutDir)\pdq3.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\pdq3.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\pdq3\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../"
PreprocessorDefinitions="USE_SIM_IMD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib"
OutputFile="$(OutDir)\pdq3.exe"
LinkIncremental="1"
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDQ-3\pdq3_cpu.c"
>
</File>
<File
RelativePath="..\PDQ-3\pdq3_debug.c"
>
</File>
<File
RelativePath="..\PDQ-3\pdq3_fdc.c"
>
</File>
<File
RelativePath="..\PDQ-3\pdq3_mem.c"
>
</File>
<File
RelativePath="..\PDQ-3\pdq3_stddev.c"
>
</File>
<File
RelativePath="..\PDQ-3\pdq3_sys.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_imd.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\PDQ-3\pdq3_defs.h"
>
</File>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_imd.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,376 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sage"
ProjectGUID="{9D0DAC36-2C75-41CD-905C-93B2F5ADF9E2}"
RootNamespace="sage"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\sage\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../"
PreprocessorDefinitions="HAVE_INT64;USE_SIM_IMD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib"
OutputFile="$(OutDir)\sage.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\sage.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\sage\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../"
PreprocessorDefinitions="HAVE_INT64;USE_SIM_IMD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib"
OutputFile="$(OutDir)\sage.exe"
LinkIncremental="1"
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\SAGE\i8251.c"
>
</File>
<File
RelativePath="..\SAGE\i8253.c"
>
</File>
<File
RelativePath="..\SAGE\i8255.c"
>
</File>
<File
RelativePath="..\SAGE\i8259.c"
>
</File>
<File
RelativePath="..\SAGE\i8272.c"
>
</File>
<File
RelativePath="..\SAGE\m68k_cpu.c"
>
</File>
<File
RelativePath="..\SAGE\m68k_mem.c"
>
</File>
<File
RelativePath="..\SAGE\m68k_parse.tab.c"
>
</File>
<File
RelativePath="..\SAGE\m68k_scp.c"
>
</File>
<File
RelativePath="..\SAGE\m68k_sys.c"
>
</File>
<File
RelativePath="..\SAGE\sage_cons.c"
>
</File>
<File
RelativePath="..\SAGE\sage_cpu.c"
>
</File>
<File
RelativePath="..\SAGE\sage_fd.c"
>
</File>
<File
RelativePath="..\SAGE\sage_lp.c"
>
</File>
<File
RelativePath="..\SAGE\sage_stddev.c"
>
</File>
<File
RelativePath="..\SAGE\sage_sys.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_imd.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\SAGE\m68k_cpu.h"
>
</File>
<File
RelativePath="..\SAGE\m68k_parse.tab.h"
>
</File>
<File
RelativePath="..\SAGE\sage_defs.h"
>
</File>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_imd.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -109,6 +109,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alpha", "alpha.vcproj", "{1
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sigma", "sigma.vcproj", "{7DDB6DF6-3837-4DE3-80D7-63181195021F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sage", "SAGE.vcproj", "{9D0DAC36-2C75-41CD-905C-93B2F5ADF9E2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDQ3", "PDQ3.vcproj", "{D4F5761A-B543-40ED-9892-12A0255C2B6D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -271,6 +275,14 @@ Global
{7DDB6DF6-3837-4DE3-80D7-63181195021F}.Debug|Win32.Build.0 = Debug|Win32
{7DDB6DF6-3837-4DE3-80D7-63181195021F}.Release|Win32.ActiveCfg = Release|Win32
{7DDB6DF6-3837-4DE3-80D7-63181195021F}.Release|Win32.Build.0 = Release|Win32
{9D0DAC36-2C75-41CD-905C-93B2F5ADF9E2}.Debug|Win32.ActiveCfg = Debug|Win32
{9D0DAC36-2C75-41CD-905C-93B2F5ADF9E2}.Debug|Win32.Build.0 = Debug|Win32
{9D0DAC36-2C75-41CD-905C-93B2F5ADF9E2}.Release|Win32.ActiveCfg = Release|Win32
{9D0DAC36-2C75-41CD-905C-93B2F5ADF9E2}.Release|Win32.Build.0 = Release|Win32
{D4F5761A-B543-40ED-9892-12A0255C2B6D}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F5761A-B543-40ED-9892-12A0255C2B6D}.Debug|Win32.Build.0 = Debug|Win32
{D4F5761A-B543-40ED-9892-12A0255C2B6D}.Release|Win32.ActiveCfg = Release|Win32
{D4F5761A-B543-40ED-9892-12A0255C2B6D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -28,14 +28,14 @@
Alpha Program Office.
*/
#ifndef ALPHA_DEFS_H_
#define ALPHA_DEFS_H_ 0
#ifndef _ALPHA_DEFS_H_
#define _ALPHA_DEFS_H_ 0
#include "sim_defs.h"
#include <setjmp.h>
#if defined (__GNUC__)
#define INLINE
#define INLINE inline
#else
#define INLINE
#endif

View file

@ -1097,7 +1097,6 @@ TX0 = ${TX0D}/tx0_cpu.c ${TX0D}/tx0_dpy.c ${TX0D}/tx0_stddev.c \
${TX0D}/tx0_sys.c ${TX0D}/tx0_sys_orig.c ${DISPLAYL}
TX0_OPT = -I ${TX0D} $(DISPLAY_OPT)
SSEMD = SSEM
SSEM = ${SSEMD}/ssem_cpu.c ${SSEMD}/ssem_sys.c
SSEM_OPT = -I ${SSEMD}
@ -1122,6 +1121,19 @@ ALPHA = ${ALPHAD}/alpha_500au_syslist.c ${ALPHAD}/alpha_cpu.c \
${ALPHAD}/alpha_mmu.c ${ALPHAD}/alpha_sys.c
ALPHA_OPT = -I ${ALPHAD} -DUSE_ADDR64 -DUSE_INT64
SAGED = SAGE
SAGE = ${SAGED}/sage_cpu.c ${SAGED}/sage_sys.c ${SAGED}/sage_stddev.c \
${SAGED}/sage_cons.c ${SAGED}/sage_fd.c ${SAGED}/sage_lp.c \
${SAGED}/m68k_cpu.c ${SAGED}/m68k_mem.c ${SAGED}/m68k_scp.c \
${SAGED}/m68k_parse.tab.c ${SAGED}/m68k_sys.c \
${SAGED}/i8251.c ${SAGED}/i8253.c ${SAGED}/i8255.c ${SAGED}/i8259.c ${SAGED}/i8272.c
SAGE_OPT = -I ${SAGED} -DHAVE_INT64 -DUSE_SIM_IMD
PDQ3D = PDQ-3
PDQ3 = ${PDQ3D}/pdq3_cpu.c ${PDQ3D}/pdq3_sys.c ${PDQ3D}/pdq3_stddev.c \
${PDQ3D}/pdq3_mem.c ${PDQ3D}/pdq3_debug.c ${PDQ3D}/pdq3_fdc.c
PDQ3_OPT = -I ${PDQ3D} -DUSE_SIM_IMD
#
# Build everything (not the unsupported/incomplete simulators)
@ -1404,3 +1416,15 @@ ${BIN}alpha${EXE} : ${ALPHA} ${SIM}
${MKDIRBIN}
${CC} ${ALPHA} ${SIM} ${ALPHA_OPT} $(CC_OUTSPEC) ${LDFLAGS}
sage : ${BIN}sage${EXE}
${BIN}sage${EXE} : ${SAGE} ${SIM}
${MKDIRBIN}
${CC} ${SAGE} ${SIM} ${SAGE_OPT} $(CC_OUTSPEC) ${LDFLAGS}
pdq3 : ${BIN}pdq3${EXE}
${BIN}pdq3${EXE} : ${PDQ3} ${SIM}
${MKDIRBIN}
${CC} ${PDQ3} ${SIM} ${PDQ3_OPT} $(CC_OUTSPEC) ${LDFLAGS}