157 9 -1:D 0 const SATSeg = 1; { SAT segment } 158 9 -1:D 0 SITSeg = 2; { SIT segement } 159 9 -1:D 0 FontSeg = 3; { font segment } 160 9 -1:D 0 ScreenSeg = 4; { screen segment } 161 9 -1:D 0 CursorSeg = 5; { cursor segment } 162 9 -1:D 0 IOSeg = 6; { IO segment } 163 9 -1:D 0 SysNameSeg = 7; { system segment names } 164 9 -1:D 0 165 9 -1:D 0 BootedMemoryInBlocks = #1000; { memory in blocks at boot time } 166 9 -1:D 0 MaxSegment = #137; { should be 2**16 - 1 } 167 9 -1:D 0 168 9 -1:D 0 SetStkBase = #60; 169 9 -1:D 0 SetStkLimit = #120; 170 9 -1:D 0 171 9 -1:D 0 {$ifc Ether3MBaud then} 172 9 -1:D 0 IOSegSize = 6; { number of blocks in the IOSeg } 173 9 -1:D 0 {$elsec} 174 9 -1:D 0 {$ifc Ether10MBaud then} 175 9 -1:D 0 IOSegSize = 3; { number of blocks in the IOSeg } 176 9 -1:D 0 {$elsec} 177 9 -1:D 0 IOSegSize = 3; { number of blocks in the IOSeg } 178 9 -1:D 0 {$endc} 179 9 -1:D 0 {$endc} 180 9 -1:D 0 181 9 -1:D 0 SysSegLength = 8; { length of name of a boot-loaded segment } 182 9 -1:D 0 183 9 -1:D 0 MMMaxBlocks = #400; { maximum number of blocks in a segment } 184 9 -1:D 0 MMMaxCount = #377; 185 9 -1:D 0 MMMaxIntSize = MMMaxBlocks-1; 186 9 -1:D 0 MMMaxExtSize = MMMaxBlocks; 187 9 -1:D 0 188 9 -1:D 0 189 9 -1:D 0 190 9 -1:D 0 type MMBit4 = 0..#17; 191 9 -1:D 0 MMBit8 = 0..#377; 192 9 -1:D 0 MMBit12 = 0..#7777; 193 9 -1:D 0 MMIntSize = 0..MMMaxIntSize; 194 9 -1:D 0 MMExtSize = 1..MMMaxExtSize; 195 9 -1:D 0 MMAddress = integer; 196 9 -1:D 0 MMPosition = (MMLowPos, MMHighPos); 197 9 -1:D 0 198 9 -1:D 0 SegmentNumber = integer; 199 9 -1:D 0 200 9 -1:D 0 SegmentKind = (CodeSegment, DataSegment); 201 9 -1:D 0 202 9 -1:D 0 SegmentMobility = (UnMovable, UnSwappable, LessSwappable, Swappable); 203 9 -1:D 0 204 9 -1:D 0 MMFreeNode = record 205 9 -1:D 0 N: MMAddress; 206 9 -1:D 0 L: integer 207 9 -1:D 0 end; 208 9 -1:D 0 209 9 -1:D 0 MMBlockArray = array[0..0] of array[0..127] of integer; 210 9 -1:D 0 211 9 -1:D 0 pMMBlockArray = ^MMBlockArray; 212 9 -1:D 0 213 9 -1:D 0 MMArray = record case Integer of 214 9 -1:D 0 1: (m: array[0..0] of MMFreeNode); 215 9 -1:D 0 2: (w: array[0..0] of Integer) 216 9 -1:D 0 end; 217 9 -1:D 0 218 9 -1:D 0 pMMArray = ^MMArray; 219 9 -1:D 0 220 9 -1:D 0 MMPointer = record case integer of 221 9 -1:D 0 1: (P: ^integer); 222 9 -1:D 0 2: (B: pMMBlockArray); 223 9 -1:D 0 3: (M: pMMArray); 224 9 -1:D 0 4: (Offset: MMAddress; 225 9 -1:D 0 Segmen: SegmentNumber) 226 9 -1:D 0 end; 227 9 -1:D 0 228 9 -1:D 0 SATentry = packed record { Segment Address Table } 229 9 -1:D 0 { **** ENTRIES MUST BE TWO WORDS LONG **** } 230 9 -1:D 0 NotResident : boolean; { 001 } 231 9 -1:D 0 Moving : boolean; { 002 } 232 9 -1:D 0 RecentlyUsed: boolean; { 004 } 233 9 -1:D 0 Sharable : boolean; { 010 } 234 9 -1:D 0 Kind : SegmentKind; { 020 } 235 9 -1:D 0 Full : boolean; { 040 } 236 9 -1:D 0 InUse : boolean; { 100 } 237 9 -1:D 0 Lost : boolean; { *** } { 200 } 238 9 -1:D 0 BaseLower : MMBit8; 239 9 -1:D 0 BaseUpper : MMBit4; 240 9 -1:D 0 Size : MMBit12 241 9 -1:D 0 end; 242 9 -1:D 0 243 9 -1:D 0 SITentry = packed record case integer of { Segment Information Table } 244 9 -1:D 0 { **** ENTRIES MUST BE EIGHT WORDS LONG **** } 245 9 -1:D 0 1: { real SIT entry } 246 9 -1:D 0 (NextSeg : SegmentNumber; 247 9 -1:D 0 RefCount : 0..MMMaxCount; 248 9 -1:D 0 IOCount : 0..MMMaxCount; 249 9 -1:D 0 Mobility : SegmentMobility; 250 9 -1:D 0 BootLoaded : Boolean; 251 9 -1:D 0 SwapInfo : record case {BootLoaded:} Boolean of 252 9 -1:D 0 True: (BootLowerAddress: Integer; 253 9 -1:D 0 BootUpperAddress: Integer; 254 9 -1:D 0 BootLogBlock: Integer); 255 9 -1:D 0 False: (DiskLowerAddress: Integer; 256 9 -1:D 0 DiskUpperAddress: Integer; 257 9 -1:D 0 DiskId: Integer) 258 9 -1:D 0 end; 259 9 -1:D 0 case SegmentKind of 260 9 -1:D 0 DataSegment: (Increment : MMIntSize; 261 9 -1:D 0 Maximum : MMIntSize; 262 9 -1:D 0 Freelist : MMAddress); 263 9 -1:D 0 CodeSegment: (Update : TimeStamp) 264 9 -1:D 0 ); 265 9 -1:D 0 2: { boot time information } 266 9 -1:D 0 (BootBlock: record 267 9 -1:D 0 CS: SegmentNumber; { initial code segment } 268 9 -1:D 0 SS: SegmentNumber; { initial stack segment } 269 9 -1:D 0 XX: Integer; { unused } 270 9 -1:D 0 VN: Integer; { system version number } 271 9 -1:D 0 FF: SegmentNumber; { first free segment number } 272 9 -1:D 0 FC: SegmentNumber; { first system code segment } 273 9 -1:D 0 DK: integer; { disk system was booted from } 274 9 -1:D 0 CH: integer { char used in booting } 275 9 -1:D 0 end) 276 9 -1:D 0 end; 277 9 -1:D 0 278 9 -1:D 0 SATarray = array[0..0] of SATentry; 279 9 -1:D 0 280 9 -1:D 0 SITarray = array[0..0] of SITentry; 281 9 -1:D 0 282 9 -1:D 0 pSAT = ^SATarray; 283 9 -1:D 0 284 9 -1:D 0 pSIT = ^SITarray; 285 9 -1:D 0 286 9 -1:D 0 MMEdge = record 287 9 -1:D 0 H: SegmentNumber; { Head } 288 9 -1:D 0 T: SegmentNumber { Tail } 289 9 -1:D 0 end; 290 9 -1:D 0 291 9 -1:D 0 SysSegName = packed array[1..SysSegLength] of Char; 292 9 -1:D 0 293 9 -1:D 0 pSysNames = ^SysNameArray; 294 9 -1:D 0 295 9 -1:D 0 SysNameArray = array[0..0] of SysSegName; 296 9 -1:D 0 297 9 -1:D 0 298 9 -1:D 0 procedure InitMemory; 299 9 1:D 0 procedure DataSeg( var S: SegmentNumber ); 300 9 2:D 0 procedure CodeOrDataSeg( var S: SegmentNumber ); 301 9 3:D 0 procedure ChangeSize( S: SegmentNumber; Fsize: MMExtSize ); 302 9 4:D 0 procedure CreateSegment( var S: SegmentNumber; 303 9 4:D 0 Fsize, Fincrement, Fmaximum: MMExtSize ); 304 9 5:D 0 procedure IncRefCount( S: SegmentNumber ); 305 9 6:D 0 procedure SetMobility( S: SegmentNumber; M: SegmentMobility ); 306 9 7:D 0 procedure DecRefCount( S: SegmentNumber ); 307 9 8:D 0 procedure SetIncrement( S: SegmentNumber; V: MMExtSize ); 308 9 9:D 0 procedure SetMaximum( S: SegmentNumber; V: MMExtSize ); 309 9 10:D 0 procedure SetSharable( S: SegmentNumber; V: boolean ); 310 9 11:D 0 procedure SetKind( S: SegmentNumber; V: SegmentKind ); 311 9 -1:D 2 procedure MarkMemory; 312 9 -1:D 0 procedure CleanUpMemory; 313 9 14:D 0 procedure FindCodeSegment( var S: SegmentNumber; Hint: SegHint ); 314 9 15:D 0 procedure EnableSwapping( Where: Integer ); 315 9 -1:D 1 procedure DisableSwapping; 316 9 17:D 0 function CurrentSegment: SegmentNumber; 317 9 17:D 1 318 9 18:D 0 exception UnusedSegment( S: SegmentNumber ); 319 9 18:D 1 {----------------------------------------------------------------------------- 320 9 18:D 1 { 321 9 18:D 1 { Abstract: 322 9 18:D 1 { UnusedSegment is raised when the memory manager encounters a segment 323 9 18:D 1 { number which references a segment which is not in use. This may mean 324 9 18:D 1 { that a bad segment number was passed to some memory manager routine 325 9 18:D 1 { or that a bad address was de-referenced. 326 9 18:D 1 { 327 9 18:D 1 { Parameters: 328 9 18:D 1 { S - Segment number of the unused segment. 329 9 18:D 1 { 330 9 18:D 1 {-----------------------------------------------------------------------------} 331 9 18:D 1 332 9 18:D 1 333 9 19:D 0 exception NotDataSegment( S: SegmentNumber ); 334 9 19:D 1 {----------------------------------------------------------------------------- 335 9 19:D 1 { 336 9 19:D 1 { Abstract: 337 9 19:D 1 { NotDataSegment is raised when the number of a code segment is passed 338 9 19:D 1 { to some memory manager routine that requires the number of a data 339 9 19:D 1 { segment. 340 9 19:D 1 { 341 9 19:D 1 { Parameters: 342 9 19:D 1 { S - Segment number of the code segment. 343 9 19:D 1 { 344 9 19:D 1 {-----------------------------------------------------------------------------} 345 9 19:D 1 346 9 19:D 1 347 9 20:D 0 exception BadSize( S: SegmentNumber; Fsize: Integer ); 348 9 20:D 2 {----------------------------------------------------------------------------- 349 9 20:D 2 { 350 9 20:D 2 { Abstract: 351 9 20:D 2 { BadSize is raised when a bad Size value is passed to some memory 352 9 20:D 2 { manager routine. This usually means that the size passed to 353 9 20:D 2 { CreateSegment or ChangeSize is greater than the maximum size or 354 9 20:D 2 { less than one. 355 9 20:D 2 { 356 9 20:D 2 { Parameters: 357 9 20:D 2 { Fsize - The bad Size value. 358 9 20:D 2 { 359 9 20:D 2 {-----------------------------------------------------------------------------} 360 9 20:D 2 361 9 20:D 2 362 9 21:D 0 exception BadIncrement( S: SegmentNumber; Fincrement: Integer ); 363 9 21:D 2 {----------------------------------------------------------------------------- 364 9 21:D 2 { 365 9 21:D 2 { Abstract: 366 9 21:D 2 { BadIncrement is raised when a bad Increment value is passed to some 367 9 21:D 2 { memory manager routine. This usually means that the increment passed 368 9 21:D 2 { to CreateSegment is greater than 256 or less than one. 369 9 21:D 2 { 370 9 21:D 2 { Parameters: 371 9 21:D 2 { Fincrement - The bad Increment value. 372 9 21:D 2 { 373 9 21:D 2 {-----------------------------------------------------------------------------} 374 9 21:D 2 375 9 21:D 2 376 9 22:D 0 exception BadMaximum( S: SegmentNumber; Fmaximum: Integer ); 377 9 22:D 2 {----------------------------------------------------------------------------- 378 9 22:D 2 { 379 9 22:D 2 { Abstract: 380 9 22:D 2 { BadMaximum is raised when a bad Maximum value is passed to some memory 381 9 22:D 2 { manager routine. This usually means that the maximum passed to 382 9 22:D 2 { CreateSegment is greater than 256 or less than one. 383 9 22:D 2 { 384 9 22:D 2 { Parameters: 385 9 22:D 2 { Fmaximum - The bad Maximum value. 386 9 22:D 2 { 387 9 22:D 2 {-----------------------------------------------------------------------------} 388 9 22:D 2 389 9 22:D 2 390 9 -1:D 2 exception FullMemory; 391 9 23:D 0 {----------------------------------------------------------------------------- 392 9 23:D 0 { 393 9 23:D 0 { Abstract: 394 9 23:D 0 { FullMemory is raised when there is not enough physical memory to 395 9 23:D 0 { satisfy some memory manager request. This is raised only after 396 9 23:D 0 { swapping segments out and compacting memory. 397 9 23:D 0 { 398 9 23:D 0 {-----------------------------------------------------------------------------} 399 9 23:D 0 400 9 23:D 0 401 9 24:D 0 exception CantMoveSegment( S: SegmentNumber ); 402 9 24:D 1 {----------------------------------------------------------------------------- 403 9 24:D 1 { 404 9 24:D 1 { Abstract: 405 9 24:D 1 { CantMoveSegment is raised when the memory manager attempts to move 406 9 24:D 1 { a segment which is UnMovable or has a non-zero IO count. 407 9 24:D 1 { 408 9 24:D 1 { Parameters: 409 9 24:D 1 { S - The number of the segment which cannot be moved. 410 9 24:D 1 { 411 9 24:D 1 {-----------------------------------------------------------------------------} 412 9 24:D 1 413 9 24:D 1 414 9 -1:D 1 exception PartNotMounted; 415 9 25:D 0 {----------------------------------------------------------------------------- 416 9 25:D 0 { 417 9 25:D 0 { Abstract: 418 9 25:D 0 { PartNotMounted is raised when 419 9 25:D 0 { 1) the memory manager attempts to swap a data segment out for 420 9 25:D 0 { the first time 421 9 25:D 0 { and 2) the partition which is to be used for swapping is no longer 422 9 25:D 0 { mounted. 423 9 25:D 0 { 424 9 25:D 0 {-----------------------------------------------------------------------------} 425 9 25:D 0 426 9 25:D 0 427 9 26:D 0 exception SwapInFailure( S: SegmentNumber ); 428 9 26:D 1 {----------------------------------------------------------------------------- 429 9 26:D 1 { 430 9 26:D 1 { Abstract: 431 9 26:D 1 { SwapInFailure is raised when the swap file cannot be found for a 432 9 26:D 1 { segment which is marked as swapped out. This is an error which 433 9 26:D 1 { should never happen in a debugged system. It usually means that 434 9 26:D 1 { there is a bug in the memory manager or that the segment tables 435 9 26:D 1 { have been clobbered. 436 9 26:D 1 { 437 9 26:D 1 { Parameters: 438 9 26:D 1 { S - The number of the segment which could not be swapped in. 439 9 26:D 1 { 440 9 26:D 1 {-----------------------------------------------------------------------------} 441 9 26:D 1 442 9 26:D 1 443 9 -1:D 1 exception EdgeFailure; 444 9 27:D 0 {----------------------------------------------------------------------------- 445 9 27:D 0 { 446 9 27:D 0 { Abstract: 447 9 27:D 0 { EdgeFailure is raised by MakeEdge when it discovers that the SIT 448 9 27:D 0 { entries are not linked together into a circular list. This is an 449 9 27:D 0 { error which should never happen in a debugged system. It usually 450 9 27:D 0 { means that there is a bug in the memory manager or that the segment 451 9 27:D 0 { tables have been clobbered. 452 9 27:D 0 { 453 9 27:D 0 {-----------------------------------------------------------------------------} 454 9 27:D 0 455 9 27:D 0 456 9 -1:D 0 exception NilPointer; 457 9 28:D 0 {----------------------------------------------------------------------------- 458 9 28:D 0 { 459 9 28:D 0 { Abstract: 460 9 28:D 0 { NilPointer is raised when a Nil pointer is used or passed to Dispose. 461 9 28:D 0 { 462 9 28:D 0 {-----------------------------------------------------------------------------} 463 9 28:D 0 464 9 28:D 0 465 9 -1:D 0 exception BadPointer; 466 9 29:D 0 {----------------------------------------------------------------------------- 467 9 29:D 0 { 468 9 29:D 0 { Abstract: 469 9 29:D 0 { BadPointer is raised when a bad pointer is passed to Dispose. 470 9 29:D 0 { 471 9 29:D 0 { Parameters: 472 9 29:D 0 { 473 9 29:D 0 {-----------------------------------------------------------------------------} 474 9 29:D 0 475 9 29:D 0 476 9 -1:D 0 exception FullSegment; 477 9 30:D 0 {----------------------------------------------------------------------------- 478 9 30:D 0 { 479 9 30:D 0 { Abstract: 480 9 30:D 0 { FullSegment is raised by New when it discovers that there is not 481 9 30:D 0 { enough room to allocate and the segment cannot be enlarged (its 482 9 30:D 0 { size has reached its maximum). 483 9 30:D 0 { 484 9 30:D 0 {-----------------------------------------------------------------------------} 485 9 30:D 0 486 9 30:D 0 487 9 -1:D 0 exception NoFreeSegments; 488 9 31:D 0 {----------------------------------------------------------------------------- 489 9 31:D 0 { 490 9 31:D 0 { Abstract: 491 9 31:D 0 { NoFreeSegments is raised when the memory manager discovers that all 492 9 31:D 0 { of the segment numbers are in use and it needs another one. This 493 9 31:D 0 { is equivalent to "Segment table full". 494 9 31:D 0 { 495 9 31:D 0 {-----------------------------------------------------------------------------} 496 9 31:D 0 497 9 31:D 0 498 9 -1:D 0 exception SwapError; 499 9 32:D 0 {----------------------------------------------------------------------------- 500 9 32:D 0 { 501 9 32:D 0 { Abstract: 502 9 32:D 0 { SwapError is raised if the one of the memory managers swapping 503 9 32:D 0 { routines is called when swapping is disabled. This is an error which 504 9 32:D 0 { should never happen in a debugged system. It usually means that 505 9 32:D 0 { there is a bug in the memory manager. 506 9 32:D 0 { 507 9 32:D 0 {-----------------------------------------------------------------------------} 508 9 32:D 0 509 9 32:D 0 510 9 32:D 0 511 9 32:D 0 512 9 -1:D 0 var SAT: pSAT; 513 9 -1:D 0 SIT: pSIT; 514 9 -1:D 2 MMFirst, MMFree, MMLast, MMHeap: SegmentNumber; 515 9 -1:D 4 MMHole: MMEdge; 516 9 -1:D 8 MMState: (MMScan1, MMScan2, MMScan3, MMScan4, MMScan5, 517 9 -1:D 10 MMScan6, MMScan7, MMScan8, MMScan9, MMScan10, 518 9 -1:D 10 MMScan11, 519 9 -1:D 10 MMNotFound, MMFound); 520 9 -1:D 10 StackSegment: SegmentNumber; 521 9 -1:D 11 FirstSystemSeg: SegmentNumber; 522 9 -1:D 12 BootFileId: Integer; 523 9 -1:D 13 SwappingAllowed: Boolean; 524 9 -1:D 14 SwapId: Integer; 525 9 -1:D 15 MemoryInBlocks: Integer; { amount of memory on this machine } 526 9 -1:D 17 527 9 -1:D 17 528 9 -1:D 17 private 529 9 -1:D 17 530 9 -1:D 17 8 0 -1:D 17 imports memory from memory;