PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 1 SBC6120 ROM Monitor BTS6120.plx 1 .TITLE SBC6120 ROM Monitor 2 3 4 ; Copyright (C) 2001-2004 by R. Armstrong, Milpitas, California. 5 ; Copyright (C) 1983 by R. Armstrong, Indianapolis, Indiana. 6 ; 7 ; This program is free software; you can redistribute it and/or modify 8 ; it under the terms of the GNU General Public License as published by 9 ; the Free Software Foundation; either version 2 of the License, or 10 ; (at your option) any later version. 11 ; 12 ; This program is distributed in the hope that it will be useful, but 13 ; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 ; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 ; for more details. 16 ; 17 ; You should have received a copy of the GNU General Public License along 18 ; with this program; if not, write to the Free Software Foundation, Inc., 19 ; 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 ; 21 22 ; This is the ROM monitor for the SBC6120 computer system, which is a Harris 23 ; HM6120 (a PDP-8 for all practical purposes) microprocessor based single board 24 ; computer. The SBC6120 is intended as a platform for developing other HM6120 25 ; systems and experimenting with various ideas for peripherals, and this gives 26 ; it a rather eclectic mix of hardware: 27 ; 28 ; * 64KW (that's 64K twelve bit WORDS) of RAM - 32KW for panel memory and 29 ; 32KW for conventional memory. 30 ; 31 ; * 32KW of EPROM used for bootstrapping - it contains this software. 32 ; 33 ; * Up to 2Mb (real eight bit bytes this time) of battery backed up, 34 ; non-volatile SRAM used as a RAM disk for OS/8. The RAM disk can be 35 ; mapped into the HM6120 panel memory space. 36 ; 37 ; * A fairly elaborate memory management system which controls the mapping 38 ; of RAM, EPROM and RAM disk into panel memory. 39 ; 40 ; * A real, straight-8, compatible console terminal interface. The control 41 ; logic is implemented in a GAL and no 6121 is used (as it is in both 42 ; models of DECmate). 43 ; 44 ; * A single digit octal display used to show POST error codes. 45 ; 46 ; * An IDE disk interface, implemented by a 8255 PPI 47 ; 48 ; This particular piece of software started life in 1983 as a bootstrap 49 ; program for an elaborate Intersil IM6100 system planned by the author. The 50 ; software was developed and tested on an 6100 emulator running on a 51 ; DECsystem-10, but it never saw any actual hardware. Although I built several 52 ; simpler 6100 based systems, the one intended for this software proved to be 53 ; too elaborate and complex and was never built. Until now, that is... 54 55 56 .HM6120 57 .STACK PAC1, POP1, PPC1, RTN1 6215 6235 6205 6225 58 .NOWARN F PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 2 BTS6120 Memory Layout BTS6120.plx 59 .TITLE BTS6120 Memory Layout 60 61 ; The EPROM in the SBC6120 is 32K twelve bit words, however the entire code 62 ; for BTS6120 currently fits within fields 0, 1 and 2. While it's executing, 63 ; however, there is a full 32K of panel RAM available for BTS6120. Currently 64 ; BTS6120 doesn't use fields three thru seven of panel RAM and these are free. 65 ; They could be used by an OS/8 program via the Copy Memory PR0 function, if 66 ; desired. 67 68 ; About Hooks: 69 ; In the FxVECTOR tables, some locations are registered as places that can be 70 ; hooked by an extension ROM. 3 words are reserved, which is enough for a CIF 71 ; or CXF, an indirect JMP, and the JMP address. Most hooks have 3 NOPs in 72 ; those three words, and execution can be continued just after those. 73 ; Hook locations are marked with a HOOK: comment 74 75 ; FIELD 0 76 ; Page Usage 77 ; ----- ---------------------------------------------------------------------- 78 ; 00000 data & initialized constants 79 ; 00200 SYSINI part 2, later overwritten by the command buffer 80 ; 00400 command line parsing & error reporting routines 81 ; 00600 RePeat, Terminal, VErsion and HElp commands 82 ; 01000 Examine and Deposit commands 83 ; 01200 examine and deposit subroutines 84 ; 01400 Block Move, ChecKsum, Clear and Fill Memory commands, Disasm stubs 85 ; 01600 Word Search and Breakpoint List commands 86 ; 02000 Breakpoint set and Remove commands and breakpoint subroutines 87 ; 02200 Proceed, Continue, SIngle step, TRace, Reset ans EXecute commands 88 ; 02400 Boot sniffer, OS/8 Bootstrap, Boot command 89 ; 02600 Partition Map command, and Disk Formatter Pass 1 90 ; 03000 Disk formatter Pass 2, Disk Format, and RAM Disk Format commands 91 ; 03200 BIN (binary paper tape image) loader and LP command 92 ; 03400 Disk (RAM and IDE) Dump and Load commands 93 ; 03600 Disk buffer ASCII dump and load subroutines 94 ; 04000 PC Partition Copy command, PE Partition Compare routine 95 ; 04200 Flash Load command, Field 0 Vectors 96 ; 04400 97 ; 04600 98 ; 05000 99 ; 05200 100 ; 05400 101 ; 05600 Front panel initialization, scan, LA, LXA, EXAM, DEP switches 102 ; 06000 Front panel CONT, START, BOOT, HALT switches, update display 103 ; 06200 SIXBIT, ASCII, decimal, and octal terminal output 104 ; 06400 address (15 bit) arithmetic, parsing and output 105 ; 06600 keyword scaner and search, decimal and octal input 106 ; 07000 miscellaneous formatted terminal input and output 107 ; 07200 command line scanner 108 ; 07400 terminal input and output primitives 109 ; 07600 control panel entry and context save 110 111 ; FIELD 1 112 ; Page Usage 113 ; ----- ---------------------------------------------------------------------- 114 ; 10000 SYSINI part 1, later overwritten by field 1 variables 115 ; 10200 ROM monitor call (PR0) processor 116 ; 10400 RAM disk R/W, pack/unpack, and battery test routines 117 ; 10600 RAM disk address calculation and diagnostic tests 118 ; 11000 IDE disk initialization and ATA IDENTIFY DEVICE command 119 ; 11200 IDE sector read/write, LBA calculation 120 ; 11400 Wait for READY or DRQ 121 ; 11600 IDE read/write sector buffer, initialize partition map 122 ; 12000 Partition map functions, IDE I/O PR0 call, read/write IDE registers 123 ; 12200 I/O buffer management, Memory Move PR0 call, cross field calling PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 3 BTS6120 Memory Layout BTS6120.plx 124 ; 12400 Extended Memory Move PR0 function, LIGHTS PR0 function, Field 1 Vectors 125 ; 12600 Flash ROM programming 126 ; 13000 127 ; 13200 to 17377 are used by command tables, error messages and help text 128 ; 17400 to 17777 are used as a temporary buffer for disk I/O 129 130 ; FIELD 2 131 ; Page Usage 132 ; ----- ---------------------------------------------------------------------- 133 ; 20000 Field 2 variables, zero page utility functions 134 ; 20200 Persistent settings support 135 ; 20400 Extension ROM management, field 2 vectors 136 ; 20600 Disassembler commands X, XP and TR. Disassembler code. 137 ; 21200 to 21277 Disassembler code 138 ; 21400 to 22377 Disassembler tables 139 ; 21600 140 ; 27600 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 4 Edit History BTS6120.plx 141 .TITLE Edit History 142 143 144 ; 1 -- Change documentation of ER and DR commands to reflect the 145 ; new format (E and D " character between the 194 ; address (or register name) and the data (instead of a 195 ; space). 196 ; 197 ; 21 -- Update the BM command to use the new 15 bit addressing. 198 ; This now allows transfers to copy more than 4K, and to 199 ; cross field boundries. Also, make it illegal for the source 200 ; address to increment out of field 7. 201 ; 202 ; 22 -- Update the CK command for 15 bit addressing. This makes it 203 ; possible to checksum more than 4K of memory in one command. 204 ; 205 ; 23 -- Move the RDMEM routine to page 6400 (the page it was on had PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 5 Edit History BTS6120.plx 206 ; 0 words free!). 207 ; 208 ; 24 -- Invent a RAM location KEY and store the WS command search 209 ; key there (not in VALUE). This fixes problems with the WS 210 ; command interacting with RDMEM. 211 ; 212 ; 25 -- Make the WS command apply the mask to the search key too. 213 ; Also, make WS poll the keyboard so that the operator may 214 ; control-C out of a long search. 215 ; 216 ; 26 -- Fix a few bugs in the BM command (these only occur when 217 ; transfers cross memory fields). Also change the syntax of 218 ; the command to accept a source address range (instead of 219 ; a destination address range). 220 ; 221 ; 27 -- Change the name of the SI command to TR (TRace). Then change 222 ; the old SN (single instruction with no register output) to 223 ; be SI. 224 ; 225 ; 30 -- Re-write the examine register to to save space. 226 ; 227 ; 31 -- Move all the register name strings to the text page. 228 ; Re-write the register typeout routines to take less space. 229 ; 230 ; 32 -- Make the examine command accept multiple operands seperated 231 ; by commas. 232 ; 233 ; 33 -- Implement the memory diagnostic routines (address test and 234 ; data test) and the MD command to execute them. 235 ; 236 ; 34 -- Invent the DEVERR routine to report device errors. Also, 237 ; re-write MEMERR to share as much code with deverr as 238 ; possible. 239 ; 240 ; 35 -- Make the memory data and address diagnostics interruptable 241 ; with a control-C (since they take a long time to execute). 242 ; 243 ; 36 -- Invent the REGTST routine to test hardware registers. This 244 ; is used to implement hardware diagnostics. 245 ; 246 ; 37 -- Implement the DPTEST routine to test hardware data paths 247 ; for faults. 248 ; 249 ; 40 -- Implement the EX command (to execute IOT instructions). 250 ; 251 ; 41 -- Implement the basic BIN loader routine (BINLOD). 252 ; 253 ; 42 -- Re-arrange code to more tightly pack memory pages (and free 254 ; another page of memory). 255 ; 256 ; 43 -- Re-define all IOT instructions to agree with the actual 257 ; hardware. 258 ; 259 ; 44 -- Re-write the CP trap and system initialization routines to 260 ; work correctly with the latest hardware design (including 261 ; the auto-start switches). 262 ; 263 ; 45 -- Add the HALT instruction trap routine (it types out the 264 ; message %HALTED @ faaaa)... 265 ; 266 ; 46 -- Ask the user before running diagnostics at startup (even 267 ; if he has enabled them via the auto-start switches). 268 ; 269 ; 47 -- Implement the TRAP routine to handle trapped IOTs. 270 ; PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 6 Edit History BTS6120.plx 271 ; 50 -- Add the code to emulate a KL8E (via trapped IOTs). 272 ; 273 ; 51 -- Fix a bug in the CP trap routine which prevented it from 274 ; recognizing SI traps correctly. 275 ; 276 ; 52 -- Make sure the TR command types out the contents of the IR 277 ; correctly (add a CLA in an opportune location). 278 ; 279 ; 53 -- Make sure the CONT routine correctly restores the CPU 280 ; registers (add another CLA !!!). 281 ; 282 ; 54 -- Revise the monitor command summary in the introduction to 283 ; be more up to date. 284 ; 285 ; 55 -- Remove the optional count operand from the TR (trace) 286 ; command and always make it execute one instruction instead. 287 ; (The user can always combine it with the RP command to get 288 ; more than one.) 289 ; 290 ; 56 -- Make the BPT instruction use opcode 6077... 291 ; 292 ; 57 -- The BPT instruction is a trapped instruction, but the 293 ; CP entry routine removes breakpoints before the TRAP 294 ; routine is called. Thus TRAP can nenver identify a BPT 295 ; instruction. Solution: don't remove breakpoints in the 296 ; CP routine, but do it in all the routines that it calls 297 ; (except TRAP, of course). 298 ; 299 ; 60 -- Make the BPTINS routine call RDMEM instead of reading memory 300 ; itself. 301 ; 302 ; 61 -- Fix the P command so that other commands after it (after 303 ; a ';') will work too. Also, move the P command to the next 304 ; memory page (with CONT) to free space. 305 ; 306 ; 62 -- Add the BT command to run the disk bootstrap (which 307 ; presently just types a message to the effect that the disk 308 ; bootstrap is not implemented). 309 ; 310 ; 63 -- Implement the following routines: CLRCPU (to clear the 311 ; user's CPU registers in RAM), CLRIO (to clear all I/O 312 ; devices via a CAF), and CLRBUS (to clear the external 313 ; bus by asserting the INITIALIZE signal). 314 ; 315 ; 64 -- Add the MR command to perform a master reset of the CPU and 316 ; hardware... 317 ; 318 ; 65 -- Insure that the terminal flag is set after the CLRIO routine 319 ; (to avoid hanging the monitor)... 320 ; 321 ; 66 -- Define the PRL instruction (READ2 FTPIEB) to pulse the CPU 322 ; RUN/HALT flip-flop. 323 ; 324 ; 67 -- Invent the INIT routine to initialize all hardware which is 325 ; important to the monitor (and call it after a hardware reset 326 ; command). 327 ; 328 ; 70 -- Make the CONTinue routine clear the console status and set 329 ; the RUN flip-flop. 330 ; 331 ; 71 -- Invent the IN (initialize) command to completely initialize 332 ; all hardware and software (it is equivalent to pressing the 333 ; RESET button !). 334 ; 335 ; 72 -- Be sure the SLU mode gets initialized properly... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 7 Edit History BTS6120.plx 336 ; 337 ; 73 -- Modify the CONOUT routine to timeout the console printer 338 ; flag and force characters out if it dosen't set after a 339 ; reasonable time (this prevents monitor hangs while debugging 340 ; programs which clear the flag). 341 ; 342 ; 74 -- Make the hardware diagnostic routine execute a master 343 ; reset (i.e. the CLEAR routine) after they are finished 344 ; (since they may leave the hardware in a strange state). 345 ; 346 ; 75 -- Change the monitor prompting character to $. 347 ; 348 ; 76 -- Implement the LP command to load paper tapes from the 349 ; console... 350 ; 351 ; 77 -- Initialize both the SLU mode and baud rate correctly when 352 ; the system is reset... 353 ; 354 ; 100 -- Go through the source and put .ORGs in places where they 355 ; have been left out... 356 ; 357 ; After almost 20 years, restart development for the SBC6120 board! 358 ; 359 ; 101 -- A "real" TLS instruction (as the SBC6120 has) doesn't clear 360 ; the AC, the way a "fake" TLS (implemented by a 6101 PIE 361 ; WRITE) does. This causes no end of problems for CONOUT and 362 ; everything that calls it! 363 ; 364 ; 102 -- Remove the terminal filler code (there's no terminal on the 365 ; planet that requires filler characters any more!) 366 ; 367 ; 103 -- Remove the TTY parameters table at TTYTAB. It's still 368 ; possible to set the TTY width and page size with the TW and 369 ; TP commands, but they now default to zero (disabled). 370 ; 371 ; 104 -- Remove the place holder code for IOT trapping and KL8 372 ; emulation. It was never used. 373 ; 374 ; 105 -- Expand the command line buffer to occupy all of RAM page 1, 375 ; and make the stack always fill whatever remains of page 0. 376 ; 377 ; 106 -- Rewrite to use the HM6120 built in hardware stack. 378 ; 379 ; 107 -- Some of the old SYSINI code was still left lying around, 380 ; and this code would clear RAM on startup. This is now a 381 ; bad idea, since it erases all our page zero vectors! 382 ; 383 ; 110 -- Unlike the 6100 software stack simulation, the 6120 PAC1/2 384 ; instructions don't clear the AC. Add a few CLAs to take 385 ; care of this difference. 386 ; 387 ; 111 -- The 6120 stack post decrements after a PUSH, so the stack 388 ; pointer needs to be initialized to the top of the stack, 389 ; not the TOS + 1... 390 ; 391 ; 112 -- Optimize the page zero constants based on the references 392 ; shown in the CREF listing. Add page zero constants for 393 ; popular numerical constants... 394 ; 395 ; 113 -- Do away with the SYNERR link (it's now the same as ZCOMERR). 396 ; 397 ; 114 -- Replace the ERROR link with a simple JMS @ZERROR, and 398 ; reclaim the page 0 RAM it used... 399 ; 400 ; 115 -- Do away with RAMINI and the page zero initialization code. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 8 Edit History BTS6120.plx 401 ; It's no longer necessary, since we now initialize all RAM 402 ; from EPROM at startup. 403 ; 404 ; 116 -- Do away with the separate IF, DF and L "registers" and treat 405 ; everything as part of the PS (aka flags) register. 406 ; 407 ; 117 -- Move around, clean up, and generally re-organize the 408 ; E, D, BM, CK, CM and FM commands. 409 ; 410 ; 120 -- Change the examine register command to ER and the deposit 411 ; register command to DR. Make some other general changes 412 ; to the syntax of the E and D commands (e.g. require commas 413 ; between multiple items in the deposit list). 414 ; 415 ; 121 -- Change the address range delimiter to "-". 416 ; 417 ; 122 -- Move around, clean up and generally re-organize another 418 ; block of code; this time everything concerned with break 419 ; points, continue, start, proceed, and CP traps. 420 ; 421 ; 123 -- CONT: needs to use RSP1 to save the monitor's stack pointer, 422 ; not LSP1 !!! 423 ; 424 ; 124 -- If a transition occurs on CPREQ L while we're in panel mode, 425 ; then the 6120 sets the BTSTRP flag in the panel status 426 ; anyway. This will cause an immediate trap back to panel 427 ; mode the instant we try to continue or proceed. The answer 428 ; is to do a dummy PRS before continuing. 429 ; 430 ; 125 -- Move around, clean up and generally re-organize the 431 ; remainder of the code. Move messages and command tables to 432 ; field 1. Change message strings to packed ASCIZ instead of 433 ; SIXBIT. 434 ; 435 ; 126 -- The packed ASCIZ OUTSTR routine still has a few non-stack 436 ; holdovers - a JMS to OUTCHR and a JMP @OUTSTR to return. 437 ; This causes no end of strange symptoms! 438 ; 439 ; 127 -- Use the new \d and \t string escape feature of PALX to put 440 ; the system generation time in the monitor. 441 ; 442 ; 130 -- Start adding RAM disk support - add DISKRD and DISKWR 443 ; 444 ; 131 -- Add MCALL (monitor call, via 6120 PR0 trapped IOT) 445 ; 446 ; 132 -- Add DISKRW ROM call function for OS/8 RAM disk driver 447 ; 448 ; 133 -- We're starting to run short of room on page zero, so move 449 ; some of the temporary variables that are used only by one 450 ; routine to the same page as that routine. Now that we're 451 ; running out of RAM this is possible. 452 ; 453 ; 134 -- Move the breakpoint tables to page 1, field zero and make 454 ; the command buffer that much (about 24 words) smaller. 455 ; Since the breakpoint tables are only addressed indirectly 456 ; anyway, this hardly made a difference to the code... 457 ; 458 ; 135 -- Fold the MEMERR routine into DANDV and simplify it a little 459 ; to save space - just type the good and bad data, and don't 460 ; bother with typing the XOR... 461 ; 462 ; 136 -- TOCT3 types the three most significant digits, not the three 463 ; least significant ! Oooppppssssss.... 464 ; 465 ; 137 -- DDUMP uses COUNT to count the words output, but TOCT4 uses PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 9 Edit History BTS6120.plx 466 ; it to count digits. Oooppssss... 467 ; 468 ; 140 -- Invent the BSETUP routine and rewrite the break point 469 ; functions to use it. This saves many words of memory. 470 ; 471 ; 141 -- Add the Format Disk (FD) command to "format" RAM disk. This 472 ; is really more of a memory diagnostic than a formatter, but 473 ; the name seems appropriate. 474 ; 475 ; 142 -- CALCDA has a off-by-one error that makes it fail for the 476 ; last 21 sectors of the RAM disk. 477 ; 478 ; 143 -- Invent the CONFRM routine and use it to make the Format Disk 479 ; command ask for confirmation before destroying anything. 480 ; 481 ; 144 -- Add the Disk downLoad command (DL). This accepts RAM disk 482 ; images in exactly the same format as output by DD. 483 ; 484 ; 145 -- Add the H (help) command and a very primitive help system 485 ; (it just types out a screen of one line descriptions for 486 ; every monitor command!). 487 ; 488 ; 146 -- Add a trace function to the DISKRW MCALL. 489 ; 490 ; 147 -- Accidentally typed a couple of JMSes when I should have 491 ; typed .PUSHJ! 492 ; 493 ; 150 -- In DLOAD, we have to use SAVCHR to get the break character 494 ; from OCTNW, not GET. 495 ; 496 ; 151 -- IOCLR L (generated by CAF) also clears the console UART, 497 ; which causes garbage if we happen to be transmitting a 498 ; character at the time. The easiest way to fix this is to 499 ; make the CLEAR routine wait for the console flag to set 500 ; (i.e. the transmitter is done) before executing a CAF. 501 ; 502 ; 152 -- The RAM DISK test at TSTUNI doesn't work if the DX pull 503 ; down resistors are removed because it fails to mask the 504 ; SRAM data to eight bits... 505 ; 506 ; 153 -- Add the infrastructure which allows the code to be split 507 ; between field 0 and 1, then move all the low level RAM disk 508 ; I/O and ROM call processing code to field 1. 509 ; 510 ; 154 -- Add SP1 and SP2 to the REGLST output (but it's still not 511 ; possible to deposit in them or examine them individually). 512 ; 513 ; 155 -- Move the ROM checksums from location 7600 to 0200. 514 ; 515 ; 156 -- Change the hardware so that the TIL311 is loaded via the 516 ; 6120 WSR (Write to Switch Register) instruction. 517 ; 518 ; 157 -- Begin adding basic IDE/ATA support. 519 ; 520 ; 160 -- Add the GETRDS (Get RAM Disk Size) and GETBAT (get backup 521 ; battery status) PR0 functions. 522 ; 523 ; 161 -- Fix a few bugs in the IDE code, and the basic drive 524 ; identification on bootup now works. 525 ; 526 ; 162 -- When programming the 8255 IDE interface, we have to change 527 ; the mode (input vs output) _before_ we set up the address 528 ; bits. If we don't then the address bits get cleared by 529 ; the #$&(*# 8255 when the mode is changed! 530 ; PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 10 Edit History BTS6120.plx 531 ; 163 -- Add Get and Set Disk Partition mapping PR0 subfunctions. 532 ; 533 ; 164 -- Add Get IDE Disk Size subfunction to PR0. 534 ; 535 ; 165 -- Add the Copy Memory subfunction to PR0. 536 ; 537 ; 166 -- Add the last missing bits of IDE disk I/O. We're now ready 538 ; to try out the OS/8 device handler. 539 ; 540 ; 170 -- INIPMP needs to do a CLL to ensure that the link is in a 541 ; known state - otherwise it can sometimes quit too soon! 542 ; 543 ; 171 -- Extend the BOOT command to boot either IDE or RAM disk. 544 ; Add the "boot sniffer" to determine whether a volume 545 ; contains a real bootstrap and use it to make "B" with no 546 ; arguments search for a bootable volume (just like a real 547 ; computer!). 548 ; 549 ; 172 -- The disk download routine needs to call PNLBUF before it 550 ; attempts to write the buffer... 551 ; 552 ; 173 -- Make illegal PR0 functions print a message and return to 553 ; BTS6120 command level. This solves the problem of how to 554 ; skip over the arguments for a call we don't understand. 555 ; 556 ; 174 -- Make the MR (master reset) command initialize the IDE 557 ; drive and reset the partition map. 558 ; 559 ; 175 -- Add the PM command to edit/view the disk partition map. 560 ; 561 ; 176 -- Completely rewrite the RAM disk formatter code to create 562 ; two commands, RF to format a RAM disk an DF to format an 563 ; IDE disk partition. 564 ; 565 ; 177 -- PMEDIT screws up the disk LUN - there's a DCA that should 566 ; have been a TAD! 567 ; 568 ; 200 -- Fix a few bugs in the DF and RF routines - FMTARG is missing 569 ; a .POPJ, and the unit number gets corrupted in FMTARG 570 ; by the TOCT4S routine, which uses WORD. 571 ; 572 ; 201 -- The pin that corresponds to A17 on a 512K chip is an 573 ; alternate chip select on the 128K chips. Worse, this extra 574 ; chip select is active HIGH, which means that A17 must always 575 ; be set before the 128K chips will do anything! 576 ; 577 ; 202 -- Clean up all the help messages and make sure they agree 578 ; with the current state of all the commands. 579 ; 580 ; 203 -- Do away with F1CALL and create PUSHJ1 instead. Both allow 581 ; field 0 routines to call field 1, however the new one takes 582 ; one less word of code at the point of the call, which 583 ; helps a lot on some pages where words are tight. 584 ; 585 ; 204 -- Invent a few more page zero constants and use them to help 586 ; out on a few more pages where space is tight. 587 ; 588 ; 205 -- Make the disk related commands (DL, DD, and DF) verify that 589 ; an IDE disk is really present by checking for DKSIZE != 0. 590 ; Also make the DISKRW PR0 call return error -1 if no disk 591 ; is attached. 592 ; 593 ; [Start porting to the SBC6120 model 2 hardware] 594 ; 595 ; 206 -- Remove all the bicolor LED stuff - it doesn't exist in PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 11 Edit History BTS6120.plx 596 ; the SBC6120 model 2. 597 ; 598 ; 207 -- The model 2 schematic accidentally switched CS1FX/CS3FX 599 ; and DIOR/DIOW in the IDE interface. Modify the code to 600 ; paramaterize all IDE interface bits and then change these 601 ; parameters to agree with the real hardware. 602 ; 603 ; 210 -- Remove all the unnecessary CLAs after PPI instructions 604 ; (in the model 2, these IOTs all clear the AC). 605 ; 606 ; 211 -- Fix the timeouts for the console flag and the LP command 607 ; so they're reasonable given the 4.9152Mhz clock of the 608 ; SBC6120 model 2. 609 ; 610 ; [SBC6120 now runs on the Model 2 hardware!] 611 ; 612 ; 212 -- Fix a nasty bug in the LBA calculation! 613 ; 614 ; 213 -- Fix TDECNW to handle unsigned numbers up to 4095 615 ; 616 ; 214 -- Change the "RAM: " in the RAM disk message to "NVR:" 617 ; to avoid confusion with the main memory.. 618 ; 619 ; 215 -- Add the PC (partition copy) command. 620 ; 621 ; 216 -- Added Memory Move Extended so that user programs may directly 622 ; access the extended (RAMdisk et al) memory area (jdk) 623 ; 624 ; [I/O board integration started] 625 ; 626 ; 217 -- changed battery test DF from 1 to 0. Also inhibited 627 ; battery message if no RAM installed (jdk) 628 ; 629 ; 220 -- added extension ROM support (jdk) 630 ; 631 ; 221 -- added PE (Partition Equal) command (jdk) 632 ; 633 ; 222 -- added persistent partition map using NVRAM (jdk) 634 ; 635 ; 223 -- change B (Boot) command to use IDE _Unit_ 0 (jdk) 636 ; 637 ; 224 -- added FL (Flash Load) command (jdk) 638 ; 639 ; 225 -- a few optimizations and clean up (jdk) 640 ; 641 ; 226 -- added vectors for TYPEIR, RANGE results (jdk) 642 ; 643 ; 227 -- changed to 3 fields (27256/512 now required) (jdk) 644 ; 645 ; 230 -- added hooks for front panel code (jdk) 646 ; 647 ; 231 -- integrated BRA's ramdisk v2 changes (jdk) 648 ; "Support two RAM disk boards (up to eight units)." 649 ; 650 ; 232 -- merged disassembler code from IOB into BTS (jdk) 651 ; 652 ; 233 -- made persistent variables more general (jdk) 653 ; 654 ; 234 -- added a couple of PRISLUs just to make sure the console is 655 ; initialized. (jdk) 656 ; 657 ; 235 -- fix in the disassembler - fix field calculation for indirect 658 ; operands of TAD/AND/ISZ/DCA (jdk) 659 ; 660 ; 236 -- Change battery status message to display only if failure PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 12 Edit History BTS6120.plx 661 ; detected, so as to be compatible with NV controllers that 662 ; don't support this test. Need to investigate better ways 663 ; to handle this (jdk). 664 ; 665 ; 237 -- Added SC (scope) command to enable backspace on DEL (jdk) 666 ; 667 ; 240 -- Added ability to set RAM disk offset. Needed for IOB 668 ; hardware issue - 1st NVRAM location not reliable. 669 ; 670 ; [End I/O board integration] 671 ; 672 ; 241 -- Add UPDISP to keep the front panel data display alive. 673 ; Call UPDISP from the CONOUT wait loop; from INCHRS, and 674 ; (of course), from the CP timer interrupt service. 675 ; 676 ; 242 -- Rewrite INCHWL to be a crude sort of co-routine, so that 677 ; we can call INCHWL and SWSCAN in parallel from the main 678 ; command loop. 679 ; 680 ; 243 -- Add SWSCAN to scan the front panel control switches. 681 ; Call SWSCAN from the main command loop at BOOTS:... 682 ; 683 ; 244 -- Add the SC command to the help. 684 ; 685 ; 245 -- Change TAD UFLAGS at XTYPIR+2 to TAD @[UFLAGS]! 686 ; 687 ; 246 -- Invent FPINIT to consistently initialize the front panel. 688 ; Use the FPDTCT flag from FPINIT everywhere to determine 689 ; whether a front panel is attached. 690 ; 691 ; 247 -- Sync the display whenever the PC or PS register is 692 ; modified, or whenever a running program halts. 693 ; 694 ; 250 -- The code in CLRCOM (for the MR command) that attempts 695 ; to reset the IDE drive is woefully inadequate. It doesn't 696 ; send an IDENTIFY DEVICE command and it doesn't make any 697 ; attempt to figure out the drive's size, so as a consequence 698 ; after an MR command BTS6120 forgets that any IDE drive is 699 ; attached. Just remove the call to IDEINI from CLRCOM - 700 ; we don't really need it! 701 ; 702 ; 251 -- Implement the LIGHTS monitor call to give the main memory 703 ; program explicit control over the DATA LEDs. 704 ; 705 ; 252 -- Some gratuitous reformatting to make the listing prettier. 706 ; Change Jim's PC and IR variable names to XPC and XIR to 707 ; avoid confusion. 708 ; 709 ; 253 -- On a real PDP-8/E, the START-CLEAR switch simply clears 710 ; the AC and all I/O devices. It does not, as I had 711 ; believed, actually start executing a program. Fix our 712 ; START (now CLEAR) key to be the same. 713 ; 714 ; 254 -- Make most (all, I think) of the front panel switches 715 ; actually print on the console in addition to the LEDs. 716 ; 717 ; 255 -- Single Step (i.e. CONTinue while the HALT switch is on) 718 ; leaves the RUN LED turned on. Bad-bad! 719 ; 720 ; 256 -- Clear the panel program mode flag in the MR, ST and B 721 ; commands (all done thru CLRCPU) and for the front panel 722 ; CLEAR key. 723 ; 724 ; 257 -- Edit 242 accidentally broke LDBUF - fix it! 725 ; PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 13 Edit History BTS6120.plx 726 ; 260 -- If the operator flips the HALT switch while a program is 727 ; doing lots of disk I/O, there's a good chance we'll miss 728 ; it. Invent CONT2 to check the state of the HALT switch 729 ; before exiting from any MUUO. 730 ; 731 ; 261 -- Implement the SPLK IOT and PANEL LOCK function. 732 ; 733 ; 262 -- Move the RLOFs around so that MCALLs don't make the RUN 734 ; LED blink. 735 ; 736 ; [End front panel integration] 737 ; 738 ; 263 -- Ensure RDSIZE is always set to zero for non-existent 739 ; SRAM chips (and the odd fields on the IOB6120!). 740 ; 741 ; 264 -- Re-arrange the startup code so that the RAMdisk battery 742 ; test occurs before the EXTROM setup. 743 ; 744 ; 265 -- Fix the RAMdisk detection code so it won't detect extra 745 ; RAMdisk chips on the original RAMdisk card (which didn't 746 ; decode EMA2!). 747 ; 748 ; 266 -- Write RDCHK1, which can correctly test the batteries on 749 ; the new DS1321 RAM disk board and the IOB6120 (which 750 ; doesn't have any low battery detection hardware!). 751 ; 752 ; 267 -- SETDAR doesn't always clear the LINK before it returns, 753 ; which causes spurious RAMdisk errors. 754 ; 755 ; 270 -- Remove some leftover debugging code in RDTEST that caused 756 ; a "phantom" RAMdisk unit 4 to always appear! 757 ; 758 ; 271 -- UPDISP reversed the rotary switch positions! 759 ; 760 ; [End of monitor edit history] 761 0271 VERSION=271 ; latest edit number 762 763 ; TODO 764 ; Make the DL/RL/DF/RF ommands display the block number in the data LEDs. 765 ; Allow the DF/RF commands to be used with RP (increment the partition 766 ; number and/or suppress the "Are you sure" prompt)... 767 ; Add a "burn in" command to exercise new systems? 768 ; Make the RP command display the iteration number in the address LEDs? 769 ; Add a "SPINDOWN" command for hard disks 770 ; THe help reports the "LP" command as "LB"! 771 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 14 SBC6120 IOTs and Definitions BTS6120.plx 772 .TITLE SBC6120 IOTs and Definitions 773 774 775 ; The console terminal interface of the SBC6120 is actually straight -8 776 ; compatible, which is a proper subset of the KL8E except that the KCF, TFL, 777 ; KIE and TSK (or SPI, depending on which manual you read!) instructions are 778 ; omitted. Console interrupts are permanently enabled, as they were in the 779 ; original PDP-8. The console interface in the SBC6120 DOES NOT use a 6121, 780 ; so there'll be none of this skip-on-flag-and-clear-it nonsense with KSF or 781 ; TSF! 782 6031 KSF=6031 ; Skip of console receive flag is set 783 6032 KCC=6032 ; Clear receive flag and AC 784 6034 KRS=6034 ; OR AC with receive buffer and DON't clear the flag 785 6036 KRB=6036 ; Read receive buffer into AC and clear the flag 786 6041 TSF=6041 ; Skip if the console transmit flag is set 787 6042 TCF=6042 ; Clear transmit flag, but not the AC 788 6044 TPC=6044 ; Load AC into transmit buffer, but don't clear flag 789 6046 TLS=6046 ; Load AC into transmit buffer and clear the flag 790 6412 PRISLU=6412 ; set console to primary SLU (03/04) 791 792 ; 8255 PPI Interface IOTs... 793 6470 PRPA=6470 ; read PPI port A 794 6471 PRPB=6471 ; " " " B 795 6472 PRPC=6472 ; " " " C 796 6473 PRCR=6473 ; " " control register 797 6474 PWPA=6474 ; write PPI port A 798 6475 PWPB=6475 ; " " " B 799 6476 PWPC=6476 ; " " " C 800 6477 PWCR=6477 ; " " control register 801 802 ; Front panel (FP612) IOTs... 803 6430 CCPR=6430 ; clear AC, HALT SW REQ and 30Hz REQ flags 804 6431 SHSW=6431 ; skip on HALT SW REQ flag 805 6432 SPLK=6432 ; skip on panel lock 806 6433 SCPT=6433 ; skip on 30Hz timer REQ flag 807 6434 RFNS=6434 ; read function switches (BOOT, EXAM, DEP, ROTSW, etc) 808 6435 RLOF=6435 ; turn off RUN LED 809 6437 RLON=6437 ; " on " " 810 ;OSR (7404) read data switches 811 ;WSR (6246) write data LEDs (when ROTSW != MD) 812 813 ; Other SBC6120 instructions... 814 6440 POST=6440 ; Display a 4 bit POST code 815 6236 BPT=PR3 ; Breakpoint trap instruction 816 817 ; Special ASCII control characters that get used here and there... 818 0000 CHNUL=000 ; A null character (for fillers) 819 0003 CHCTC=003 ; Control-C (Abort command) 820 0007 CHBEL=007 ; Control-G (BELL) 821 0010 CHBSP=010 ; Control-H (Backspace) 822 0011 CHTAB=011 ; Control-I (TAB) 823 0012 CHLFD=012 ; Control-J (Line feed) 824 0015 CHCRT=015 ; Control-M (carriage return) 825 0017 CHCTO=017 ; Control-O (Suppress output) 826 0021 CHXON=021 ; Control-Q (XON) 827 0022 CHCTR=022 ; Control-R (Retype command line) 828 0023 CHXOF=023 ; Control-S (XOFF) 829 0025 CHCTU=025 ; Control-U (Delete command line) 830 0033 CHESC=033 ; Control-[ (Escape) 831 0177 CHDEL=177 ; RUBOUT (Delete) 832 833 ; OPR microinstructions that load the AC with various special constants... 834 7200 NL0000=CLA ; all models 835 7201 NL0001=CLA IAC ; all models 836 7326 NL0002=CLA CLL CML RTL ; all models PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 15 SBC6120 IOTs and Definitions BTS6120.plx 837 7332 NL2000=CLA CLL CML RTR ; all models 838 7350 NL3777=CLA CLL CMA RAR ; all models 839 7330 NL4000=CLA CLL CML RAR ; all models 840 7352 NL5777=CLA CLL CMA RTR ; all models 841 7346 NL7775=CLA CLL CMA RTL ; all models 842 7346 NLM3=NL7775 ; all models 843 7344 NL7776=CLA CLL CMA RAL ; all models 844 7344 NLM2=NL7776 ; all models 845 7240 NL7777=CLA CMA ; all models 846 7240 NLM1=NL7777 ; all models 847 7325 NL0003=CLA STL IAC RAL ; PDP-8/I and later 848 7307 NL0004=CLA CLL IAC RTL ; PDP-8/I and later 849 7327 NL0006=CLA STL IAC RTL ; PDP-8/I and later 850 7333 NL6000=CLA STL IAC RTR ; PDP-8/I and later 851 7203 NL0100=CLA IAC BSW ; PDP-8/E and later 852 7215 NL0010=CLA IAC R3L ; HM6120 only PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 16 SBC6120 Memory Mapping Hardware BTS6120.plx 853 .TITLE SBC6120 Memory Mapping Hardware 854 855 856 ; The SBC6120 has three memory subsystems - 64K words of twelve bit RAM, 857 ; 8K words of 12 bit EPROM (actually the EPROM is 16 bits wide, but the 858 ; hardware just throws away the extra four bits), and up to 2Mb of 8 bit 859 ; battery backed up SRAM for a RAM disk. 860 ; 861 ; The HM6120 on the other hand, has only two memory spaces - panel memory 862 ; and main memory, and each of these is limited to 32K words. The SBC6120 863 ; implements a simple memory mapping scheme to allow all three memory 864 ; subsystems to fit in the available address space. Up to four different 865 ; memory maps are possible, although only three are currently implemented. 866 ; 867 ; The memory map in use is selected by four IOT instructions, MM0, MM1 868 ; MM2 and (what else) MM3. Memory map changes take place immediately with 869 ; the next instruction fetch - there's no delay until the next indirect JMP 870 ; the way there is with a CIF instruction. 871 ; 872 ; The four memory maps implemented by the SBC6120 are: 873 ; 874 ; * Map 0 uses the EPROM for all direct memory accesses, including instruction 875 ; fetch, and uses the RAM for all indirect memory accesses. This is the 876 ; mapping mode set by the hardware after a power on reset. 877 ; 878 ; * Map 1 uses the RAM for all direct memory accesses, including instruction 879 ; fetch, and uses the EPROM for all indirect memory references. This mode 880 ; is the "complement" of map 0, and it's used by the panel memory bootstrap 881 ; to copy the EPROM contents to RAM. 882 ; 883 ; * Map 2 uses the RAM for all memory accesses, regardless. This is the 884 ; mapping mode used during almost all operation after booting. 885 ; 886 ; * Map 3 is the same as map 2, except that the RAM disk memory is enabled 887 ; for all indirect accesses. BEWARE - RAM disk memory is only eight bits 888 ; wide and reads and writes to this memory space only store and return the 889 ; lower byte of a twelve bit word. This mode is used only while we're 890 ; accessing the RAM disk. 891 ; 892 ; IMPORTANT! The memory mapping mode affects only 6120 control panel memory 893 ; accesses. Main memory is always mapped to RAM regardless of the mapping 894 ; mode selected. 895 896 ; DIRECT INDIRECT 897 ; -------- -------- 898 6400 MM0=6400 ; EPROM RAM (automatically selected by a RESET) 899 6401 MM1=6401 ; RAM EPROM (used during system initialization) 900 6402 MM2=6402 ; RAM RAM (used almost all the time) 901 6403 MM3=6403 ; RAM DISK (used to access RAM disk only) PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 17 System Startup and POST Codes BTS6120.plx 902 .TITLE System Startup and POST Codes 903 904 905 ; Getting the SBC6120 monitor up and running after a power up is a little 906 ; harder than we might wish. Our first problem is that we're actually 907 ; executing code from the EPROM now, and a lot of the usual PDP-8 techniques 908 ; of "self manipulation" (e.g. a JMS instruction!) won't work because the 909 ; program store isn't writable. Our second problem is that all of panel 910 ; fields 0 and 1 are mapped to EPROM, and there's no RAM anywhere in these 911 ; fields at all, not even in page zero. 912 ; 913 ; Our final problem is that we can't even be sure that all the hardware is 914 ; working correctly at this point. If some part isn't working, for example, 915 ; the RAM, we'd like to provide at least some kind of diagnostic message 916 ; before we end up lost forever. The minimum set of system components that 917 ; this monitor needs to have working before it can print a prompt and execute 918 ; commands is 1) the CPU, 2) the ROM, 3) the RAM, and 4) the console terminal. 919 ; 920 ; This means we need to accomplish two things during a cold boot - first, 921 ; to execute a simple power on self test (aka POST), and second, to copy this 922 ; monitor's code from EPROM to panel RAM where we can execute it without 923 ; restriction. 924 ; 925 ; The SBC6120 has a single digit LED display that the program can set, via 926 ; the POST instruction. At the beginning of each step in testing and 927 ; initialization we set this digit to a particular value, and then if that 928 ; test or startup part fails, we simply halt and the display remains at the 929 ; last value set. The digits and their associated failure modes are: 930 ; 931 ; 7 - CPU failure (or it's not a 6120) 932 ; 6 - panel RAM bootstrap failure 933 ; 5 - RAM checksum failure 934 ; 4 - memory test failure 935 ; 3 - currently unused (reserved for 6121 failure?) 936 ; 2 - console terminal failure 937 ; 1 - panel monitor running (success!) 938 ; 0 - user (main memory) program running PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 18 System Startup, Part 1 BTS6120.plx 939 .TITLE System Startup, Part 1 940 941 942 ; This code lives in field one, page zero of the EPROM and it's the first 943 ; thing that gets executed after a power on clear. Its main job is to get 944 ; the SBC6120 memory initialized, which it does it with these steps: 945 ; 946 ; 1 - execute a simple CPU test 947 ; 2 - execute a very simple RAM test 948 ; 3 - copy EPROM to panel RAM 949 ; 4 - verify the firmware checksum 950 ; 5 - execute an extensive test on the remaining memory 951 ; 952 ; After it's done, it jumps to the second phase of initialization, which 953 ; lives in field zero. When this code starts we're in memory mapping mode 954 ; zero, which means that all instructions are being executed from EPROM and 955 ; RAM can be addressed only indirectly. When it finishes, all code will be 956 ; in panel RAM and we'll be running in memory mapping mode two, which means 957 ; that all memory accesses go to RAM and the EPROM is inaccesible. 958 ; 959 ; After system initialization is complete, all this code is over written 960 ; with page zero variables and storage for field one. 961 10200 .FIELD 1 962 10000 .PAGE 0 963 964 ; Location zero of field 1 (and field 0, for that matter) must contain a 965 ; zero for the checksum routine. See the code at ROMCHK: for a discussion. 966 10000 0000 0000 967 968 ; The first step is the CPU test, which is trivially simple. We just 969 ; verify that we're actually running on a HM6120 and let it go at that... 970 10001 6447 SYSINI: POST+7 ; set the POST code to 7 971 10002 7215 CLA IAC R3L ; Only a 6120 has the R3L instruction 972 10003 1177 TAD [-10] ; Did we get the right answer? 973 10004 7440 SZA ; ??? 974 10005 5005 JMP . ; Nope - halt forever 975 976 ; Before we copy the boot code to panel RAM, do a primitive (and it's really 977 ; primitive!) test of RAM just to make sure there's something there we can 978 ; read and write. Remember that at this point we're using memory map 0, so 979 ; all direct references are to EPROM, but all indirect references are to RAM. 980 10006 6446 POST+6 ; set the POST code to six 981 10007 6276 SPD ; be sure we're accessing panel memory now! 982 10010 7200 CLA ; ... 983 10011 1176 TAD [2525] ; write an alternating bit pattern 984 10012 3575 DCA @[ROMCPY] ; ... to RAM location zero 985 10013 1174 TAD [5252] ; and write the complement to location 1 986 10014 3573 DCA @[ROMCPY+1] ; ... 987 10015 1575 TAD @[ROMCPY] ; now read them both back 988 10016 1573 TAD @[ROMCPY+1] ; and add them up 989 10017 7040 CMA ; and the result should be -1 990 10020 7440 SZA ; ???? 991 10021 5021 JMP . ; low RAM failure 992 993 ; Copy all of the EPROM moving code, which is six words starting at the label 994 ; ROMCPY, from EPROM to exactly the same location in RAM. There's no way to 995 ; use a loop to do this since we don't have any RAM that we can access directly 996 ; to use as a pointer! 997 10022 1040 TAD ROMCPY ; copy this one word from EPROM 998 10023 3575 DCA @[ROMCPY] ; ... to RAM 999 10024 1041 TAD ROMCPY+1 ; and do it for the entire routine 1000 10025 3573 DCA @[ROMCPY+1] ; ... 1001 10026 1042 TAD ROMCPY+2 ; ... 1002 10027 3572 DCA @[ROMCPY+2] ; ... 1003 10030 1043 TAD ROMCPY+3 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 19 System Startup, Part 1 BTS6120.plx 1004 10031 3571 DCA @[ROMCPY+3] ; ... 1005 10032 1044 TAD ROMCPY+4 ; ... 1006 10033 3570 DCA @[ROMCPY+4] ; ... 1007 10034 1045 TAD ROMCPY+5 ; ... 1008 10035 3567 DCA @[ROMCPY+5] ; ... 1009 1010 ; Now it gets tricky. At this instant we're still running in EPROM, and the 1011 ; first two instructions (at ROMCP0) get executed from EPROM. As soon as we 1012 ; execute the MM1 at ROMCPY:, however, the very next instruction is fetched 1013 ; from RAM. This should work, because the previous code has copied the six 1014 ; words that make up the ROMCPY loop from EPROM to exactly the same location 1015 ; in RAM. 1016 ; 1017 ; The loop the copies an entire field from EPROM to RAM, executing from RAM 1018 ; the whole time. It actually over writes itself in the process, but since it 1019 ; over writes itself with a copy of the exact same code we should be OK. By 1020 ; the time it falls thru the ISZ at the end of the loop, the subsequent code 1021 ; should exist in RAM. 1022 ; 1023 ; After copying field 1, we copy fields 2, 3, and 0. There is another 1024 ; subtlety here. The next step will be to checksum the RAM copy, but we're 1025 ; modifying it before we get there! Without some adjustment, the checksum 1026 ; will fail. As it turns out, there is a simple fix- the self-modifying code 1027 ; location is initialized with the value we expect it to have when the copy 1028 ; is complete. This actual instance of the value is never actually executed, 1029 ; but it is seen by the checksum generator and incorporated into the checksum, 1030 ; so everything works out. Although the first time thru we executed ROMCP0 1031 ; from EPROM, the next time thru we execute it from RAM, which is OK because 1032 ; it got copied during the first pass. 1033 ; BTW, Field 3 gets copied to RAM, but BTS6120 is only 3 fields long. Since 1034 ; there won't be a valid checksum in field 3, we will ignore it. 1035 ; 1036 ; Say goodbye to memory map 0 - we'll never need it again! 1037 1038 ; This loop copies all of a field, except location 0, from EPROM to RAM. 1039 10036 7201 ROMCP0: CLA IAC ; always start with location 1, not zero 1040 10037 3566 DCA @[0] ; save the address pointer here 1041 10040 6401 ROMCPY: MM1 ; (1) address RAM directly, EPROM indirectly 1042 10041 1400 TAD @0 ; (2) and load a word from EPROM 1043 10042 6402 MM2 ; (3) address RAM for all memory accesses 1044 10043 3400 DCA @0 ; (4) and store the word in RAM 1045 10044 2000 ISZ 0 ; (5) have we done an entire field? 1046 10045 5040 JMP ROMCPY ; (6) nope - keep copying 1047 10046 6214 RDF ; which field did we just copy? 1048 10047 7450 SNA ; was it 0? 1049 10050 5056 JMP ROMCP1 ; yes, finished copying fields 1050 10051 1165 TAD [CDF 1] ; no, make it a CDF to the next field 1051 10052 0164 AND [7737] ; wrap it around from CDF 3 to CDF 0 1052 10053 3054 DCA .+1 ; and store it to be executed 1053 10054 6201 CDF 0 ; change to new field *** see note above *** 1054 10055 5036 JMP ROMCP0 ; and copy it 1055 10056 ROMCP1: 1056 1057 ; When we leave this loop, we're using memory map 2 which means panel RAM 1058 ; is used everywhere and the EPROM is inaccessible. We'll stay in this mapping 1059 ; mode forever, except when we're accessing the RAM disk. 1060 1061 ; Each field of the panel ROM contains a 12 bit checksum, put there by the 1062 ; PDP2HEX program and calculated so that the sum of all words in the field, 1063 ; including the checksum word, will be zero. Now we'll compute and verify the 1064 ; checksum of both RAM fields, which proves that our RAMs work, that the 1065 ; EPROMS were programmed correctly, and that we copied them correctly. 1066 ; 1067 ; It might seem a better to do this before on the EPROMs before we've copied 1068 ; them to RAM, but the answer is that it's just impossible to compute a PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 20 System Startup, Part 1 BTS6120.plx 1069 ; checksum using memory map 0 - there's no directly addressible RAM to use for 1070 ; address pointers or for storing the sum! 1071 ; 1072 ; Another issue here is the use of self-modifying code here and in the ROM 1073 ; copy function. Here, like above, we finesse the issue by initializing the 1074 ; modified location to the value it's expected to have (CDF 1) when this field 1075 ; is checksummed. 1076 ; 1077 ; One last subtle point is that we're keeping an address pointer in location 1078 ; zero of RAM, which wasn't in the EPROM when PDP2HEX calculated its checksum. 1079 ; This actually works by accident (er - excuse me, "Design"), since we keep 1080 ; our pointer in location zero of RAM, it will have the value zero when we 1081 ; checksum it. Coincidentally, this is exactly the same value that's in 1082 ; location zero of the ROM image. 1083 1084 ; This loop checksums one RAM field... 1085 10056 6445 POST+5 ; set the POST code to five 1086 10057 6221 CDF 2 ; checksum field 2 first 1087 10060 7201 ROMCHK: CLA IAC ; and start with location 1 (skip zero) 1088 10061 3000 DCA 0 ; ... 1089 10062 1400 ROMCH0: TAD @0 ; add up another word from RAM 1090 10063 2000 ISZ 0 ; have we done an entire field? 1091 10064 5062 JMP ROMCH0 ; nope - keep adding 1092 10065 7440 SZA ; yes - did the checksum pass? 1093 10066 5066 JMP . ; RAM checksum failure 1094 10067 6214 RDF ; get the field we just did 1095 10070 7450 SNA ; was it field 0? 1096 10071 5076 JMP ROMCH1 ; yes, we're done 1097 10072 1163 TAD [6171] ; no, make it previous CDF by adding [CDF 0]-10 1098 10073 3074 DCA .+1 ; and store for execution next 1099 10074 6211 CDF 1 ; *** see note above *** 1100 10075 5060 JMP ROMCHK ; continue checksumming 1101 10076 ROMCH1: 1102 1103 ; The next step is to run a memory test on the remaining fields (2 thru 7) 1104 ; of panel memory and all fields of main memory. It's not a very sophisticated 1105 ; test - it just writes each memory location with its address in the first pass 1106 ; and then reads it back in the second, but it does prove that there's at least 1107 ; some memory out there listening. 1108 ; 1109 ; Before we do that, however, we do an even simpler test to verify that the 1110 ; panel data flag is working and that main memory and panel memory are two 1111 ; separate and distinct memory spaces... 1112 1113 ; Make sure that panel memory and main memory are distinct... 1114 10076 6444 POST+4 ; set the POST code to four 1115 10077 7240 STA ; put -1 in location 0 of panel memory 1116 10100 3566 DCA @[0] ; ... 1117 10101 6266 CPD ; and then put 0 in the same location 1118 10102 3566 DCA @[0] ; ... of main memory 1119 10103 6276 SPD ; back to panel memory 1120 10104 2566 ISZ @[0] ; and increment -1 1121 10105 5105 JMP . ; if it doesn't skip something is wrong 1122 1123 ; Test all eight fields of main memory... 1124 ; CLA ; and start testing with field zero 1125 10106 6266 CPD ; address main memory again 1126 10107 4122 MEMTS1: JMS FLDTST ; test this field, halt if it's bad 1127 10110 7440 SZA ; have we wrapped around to field 0 again ? 1128 10111 5107 JMP MEMTS1 ; no - test the next field 1129 1130 ; Then test only fields 3 thru 7 of panel memory... 1131 10112 6276 SPD ; address panel memory this time 1132 ;*** change this constant to 40 if testing extension ROM code in EPROM 1133 10113 1162 TAD [30] ; start testing with field 2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 21 System Startup, Part 1 BTS6120.plx 1134 10114 4122 MEMTS2: JMS FLDTST ; test this field, halt if it's bad 1135 10115 7440 SZA ; ... 1136 10116 5114 JMP MEMTS2 ; ... 1137 1138 ; As the last step in this part of the initialization, test the RAMdisk 1139 ; batteries (if a RAMdisk is installed). The DS1221 version of the RAMdisk 1140 ; requires that the battery test be performed before ANY other access to 1141 ; the RAMdisk array, so this has to happen before we can initialize the 1142 ; extension ROM. BTW, note that a) we have no stack yet, and b) the 1143 ; CK1221 routine also lives in field one, and c) CK1221 is only called 1144 ; once, from here! 1145 10117 4561 JMS @[CK1221] ; go test the DS1221 battery 1146 ; CDF 1 ; (CK1221 changes the DF!) 1147 1148 ; System initialization, part 1, is finished. The remainder of the code 1149 ; lives in field zero... 1150 10120 6203 CXF 0 1151 10121 5560 JMP @[SYSIN2] 1152 1153 ; This subroutine will test one field of either main memory or panel memory. 1154 ; It's a fairly simple minded test - it just writes each location with its 1155 ; address in the first pass and then reads it back in the second pass. If the 1156 ; test fails it just halts - there is no error return! 1157 10122 0000 FLDTST: 0 ; enter here with the field in the AC 1158 10123 1157 TAD [CDF 0] ; make a CDF instruction out of it 1159 10124 3125 DCA .+1 ; and execute it inline 1160 10125 7000 NOP ; gets over written with a CDF 1161 10126 3000 DCA 0 ; reset the address pointer 1162 10127 1000 FLDTS1: TAD 0 ; write each word with its address 1163 10130 3400 DCA @0 ; ... 1164 10131 2000 ISZ 0 ; have we done all 4K? 1165 10132 5127 JMP FLDTS1 ; nope - keep going 1166 10133 3000 DCA 0 ; yes - reset the address pointer 1167 10134 1000 FLDTS2: TAD 0 ; and make another pass to test 1168 10135 7041 CIA ; ... what we wrote 1169 10136 1400 TAD @0 ; ... 1170 10137 7440 SZA ; does this location contain the right value? 1171 10140 5140 JMP . ; no - just halt 1172 10141 2000 ISZ 0 ; yes - keep going for all 4K 1173 10142 5134 JMP FLDTS2 ; ... 1174 10143 6214 RDF ; get the data field we just tested 1175 10144 1156 TAD [10] ; and increment it for the caller 1176 10145 0155 AND [70] ; remove any overflow bits 1177 10146 5522 JMP @FLDTST ; return the next field to the caller 1178 10155 0070 10156 0010 10157 6201 10160 0201 10161 0540 10162 0030 10163 6171 10164 7737 10165 6211 10166 0000 10167 0045 10170 0044 10171 0043 10172 0042 10173 0041 10174 5252 10175 0040 10176 2525 10177 7770 1179 10200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 22 System Startup, Part 2 BTS6120.plx 1180 .TITLE System Startup, Part 2 1181 1182 1183 ; This routine is the second phase of system initialization, and it lives 1184 ; in page one of field zero. It's called at the end of the first phase, and 1185 ; it will: 1186 ; 1187 ; 1 - test and initialize any extra hardware (e.g. 6121 chips) 1188 ; 2 - test and initialize the console terminal 1189 ; 3 - initialize any RAM that needs it 1190 ; 4 - print a sign on message 1191 ; 5 - jump to the monitor restart address 1192 ; 1193 ; After this code finishes, the monitor is running and a prompt will have been 1194 ; printed on the terminal. This code code gets overwritten immediately by the 1195 ; monitor's command line buffer, which also lives in page 1 of field 0. 1196 00200 .FIELD 0 1197 00200 .PAGE 1 1198 1199 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 1200 ; HEX format) stores a checksum of ROM field 0 in location 00200, which will 1201 ; later be used by the POST... 1202 00200 ROMCK0: .BLOCK 1 1203 1204 1205 ; Create a software stack and initialize the stack pointer.... 1206 00201 6203 SYSIN2: CXF 0 ; Be sure the IB and DF are both zero 1207 00202 6276 SPD ; Address CP memory with indirect cycles 1208 00203 7200 CLA ; just in case... 1209 00204 1377 TAD [STACK] ; reset the 6120 stack pointer 1210 00205 6217 LSP1 ; ... 1211 1212 ; check for an extension ROM in ramdisk memory at DAR=0000, DF=1, O=0000. 1213 ; The check looks for a signature of 'SB' 'C6' at the start, and a valid 1214 ; checksum. 1215 00206 6443 POST+3 ; set the POST code to three 1216 00207 6222 CIF 2 1217 00210 6205 .PUSHJ @[EXTROM] ; and call the extension ROM check 00211 5776 1218 1219 ; The next stage in initialization is to test the console terminal. Since 1220 ; the SBC6120 hardware doesn't have a loopback mode we can't really verify that 1221 ; data is being sent and received correctly, but we can at least test that the 1222 ; flags set and clear at appropriate times. That way we'll know, at last, that 1223 ; we won't hang forever if we do a "TLS; JMP .-1" loop. 1224 00212 6442 POST+2 ; set the POST code to two 1225 00213 7200 CLA ; send a null character to the console 1226 00214 6046 TLS ; ... 1227 00215 6041 TSF ; and then wait for the flag to set 1228 00216 5215 JMP .-1 ; waiting forever, if necessary! 1229 00217 6042 TCF ; clear the console flag 1230 00220 6041 TSF ; and then test it again 1231 00221 7410 SKP ; good - it _isn't_ set! 1232 00222 5222 JMP . ; bad - it's still set, so the console fails 1233 00223 6046 TLS ; send another null 1234 00224 6041 TSF ; and be sure it sets one more time 1235 00225 5224 JMP .-1 ; ... 1236 1237 ; Now make sure we can clear the keyboard input flag, and that KCC also 1238 ; clears the AC. The latter proves that there is at least some hardware out 1239 ; there controlling the C lines for the console terminal, although it doesn't 1240 ; guarantee that we can receive data. 1241 00226 7240 STA ; Load the AC with -1 1242 00227 6032 KCC ; Clear the keyboard flag and the AC 1243 00230 7440 SZA ; Verify that the AC got cleared PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 23 System Startup, Part 2 BTS6120.plx 1244 00231 5231 JMP . ; Nope - console test failed! 1245 00232 6031 KSF ; And test the keyboard flag 1246 00233 7410 SKP ; Good - it _isn't_ set! 1247 00234 5234 JMP . ; Bad - the keyboard test failed 1248 1249 ; Set the control panel entry vector in 7777 to be a "JMP CPSAVE" instruction. 1250 ; We have to do this in a rather awkward way because PALX won't assemble a 1251 ; current page reference to CPSAVE unless we're actually on the same page as 1252 ; CPSAVE! 1253 00235 6441 SYSIN3: POST+1 ; the monitor is up and running now 1254 00236 1375 TAD [CPSAVE&177 | 5200] 1255 00237 3774 DCA @[7777] 1256 1257 ; Do any RAM initialization that needs to be done... 1258 00240 6205 .PUSHJ @[RAMINIT] 00241 5773 1259 1260 ; Figure out if we have a front panel (FP612) and, if we do, turn it on... 1261 00242 6205 .PUSHJ @[FPINIT] 00243 5772 1262 1263 ; Type out the system name... 1264 00244 6205 .PUSHJ @ZCRLF ; First start on a new line 00245 5506 1265 00246 6205 .PUSHJ @[HELLO] ; Finally add our name and version 00247 5771 1266 1267 ; Now print information about the extension ROM, if one was found, but 1268 ; it did not initialize properly. Error 2 means that its checksum was 1269 ; invalid. Error 3 or greater means that the ROM initialization was 1270 ; called but it returned this error code. 1271 00250 1370 TAD [-2] ; compare the status code to 2 1272 00251 1033 TAD EXTFLAG 1273 00252 7510 SPA 1274 00253 5263 JMP NOXRMES ; either there is no ROM, or it was OK 1275 1276 00254 4507 JMS @ZINLMES ; say 1277 00255 4332 XRMES1 ; "EXT: Error " 1278 00256 1033 TAD EXTFLAG ; and display the error code 1279 00257 6205 .PUSHJ @ZTDECNW ; ... 00260 5504 1280 00261 6205 .PUSHJ @ZCRLF ; followed by a newline 00262 5506 1281 00263 NOXRMES: 1282 1283 ; Now we are ready to initialize the RAM disk array by first testing the 1284 ; backup battery and then individually testing each of the eight RAM chips to 1285 ; determine a) if one is installed, and b) how big it is. IMPORTANT - because 1286 ; of the way the DS1321 works, we MUST test the backup battery before any 1287 ; other accesses to the RAM disk! The RDTEST routine will automatically 1288 ; initialize the RDSIZE array with the size of each RAM disk chip that it 1289 ; discovers... 1290 00263 4527 JMS @ZPUSHJ1 ; first determine the type of the RAMDisk 1291 00264 0603 RDCHK1 ; .... and set RDTYPE 1292 00265 4507 JMS @ZINLMES ; say 1293 00266 4240 RAMMS1 ; "NVR: " 1294 00267 4527 JMS @ZPUSHJ1 ; (cross field call) 1295 00270 1446 RDTEST ; test all eight RAM disk units 1296 00271 6205 .PUSHJ @ZTDECNW ; type out the total RAM size 00272 5504 1297 00273 4507 JMS @ZINLMES ; say 1298 00274 4245 RAMMS3 ; "KB" 1299 00275 6211 CDF 1 ; the battery OK flag lives in field 1 1300 00276 1767 TAD @[BATTOK] ; get the battery status flag 1301 00277 6201 CDF 0 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 24 System Startup, Part 2 BTS6120.plx 1302 00300 7450 SNA ; if it's zero the battery status is unknown 1303 00301 5311 JMP NORDM ; ... so say nothing 1304 00302 7700 SMA CLA ; -1 means battery OK 1305 00303 5307 JMP RDBFAI ; and +1 is battery fail 1306 00304 4507 JMS @ZINLMES ; say 1307 00305 4250 BOKMSG ; ... "- Battery OK" 1308 00306 5311 JMP NORDM ; and we're done 1309 00307 4507 RDBFAI: JMS @ZINLMES ; say 1310 00310 4262 BFAMSG ; ... "- Battery FAIL" 1311 00311 6205 NORDM: .PUSHJ @ZCRLF ; finish the status report and we're done 00312 5506 1312 1313 1314 ; Finally, probe the IDE bus for any drive that might be attached. First 1315 ; we have to initialize the 8255 and reset the IDE bus, and then we can send 1316 ; an ATA IDENTIFY DEVICE command to the drive. The DISKID routine will 1317 ; extract the drive's capacity, in MB, from that and leave the result at 1318 ; DKSIZE. DISKID also leaves the first 256 bytes of the drive's response in 1319 ; the DSKBUF, and we can use that to type out the drive's make and model, 1320 ; which appears there in plain ASCII. 1321 00313 4507 JMS @ZINLMES ; say 1322 00314 4275 IDEMS1 ; "IDE: " 1323 00315 4527 JMS @ZPUSHJ1 ; (cross field call) 1324 00316 1013 IDEINI ; initialize the IDE interface 1325 00317 7430 SZL ; is there a drive attached? 1326 00320 5346 JMP SYSIN4 ; nope - quit now 1327 00321 4527 JMS @ZPUSHJ1 ; (cross field call) 1328 00322 1042 DISKID ; send an IDENTIFY DEVICE command to the drive 1329 00323 7630 SZL CLA ; did it work ? 1330 00324 5346 JMP SYSIN4 ; nope - there's no disk there after all 1331 00325 6211 CDF 1 ; disk data lives in field 1 1332 00326 3766 DCA @[DSKBUF+135] ; (make the model string ASCIZ) 1333 00327 1765 TAD @[DKSIZE] ; get the total disk size 1334 00330 6201 CDF 0 ; ... 1335 00331 7450 SNA ; is the disk size zero ? 1336 00332 5343 JMP SYSIN7 ; yes - this disk is "unsupported" ! 1337 00333 6205 .PUSHJ @ZTDECNW ; and type it out in decimal 00334 5504 1338 00335 4507 JMS @ZINLMES ; say 1339 00336 4302 IDEMS2 ; "MB" 1340 00337 1364 TAD [DSKBUF+66-1] ; point to the make/model string 1341 00340 6205 .PUSHJ @[TASZF1] ; and type that out, in ASCII 00341 5763 1342 00342 5350 JMP SYSIN5 ; go type a CRLF and we're done 1343 1344 ; Here if an unsupported (i.e. one which does not support LBA addressing) 1345 ; is detected... 1346 00343 4507 SYSIN7: JMS @ZINLMES ; say 1347 00344 4320 IDEMS4 ; "not supported" 1348 00345 5350 JMP SYSIN5 ; ... 1349 1350 ; Here if no IDE disk is detected... 1351 00346 4507 SYSIN4: JMS @ZINLMES ; and say 1352 00347 4307 IDEMS3 ; "NONE" 1353 00350 6205 SYSIN5: .PUSHJ @ZCRLF ; finish the line and we're done 00351 5506 1354 1355 ; HOOK: End of startup, after BTS6120 messages but before command prompt. 1356 ; Unlike most hooks, this one does not have continuation code after the 1357 ; three hook words; the interceptor must instead jump to RESTA, which 1358 ; is also a hook and therefore known to the extension ROM. 1359 00352 5524 SYSIN9: JMP @ZRESTA ; And we're ready for commands... 1360 00353 7000 NOP ; Hook area for extension ROM 1361 00354 7000 NOP 1362 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 25 System Startup, Part 2 BTS6120.plx 00363 6255 00364 7465 00365 0022 00366 7535 00367 0032 00370 7776 00371 0701 00372 5600 00373 4200 00374 7777 00375 5202 00376 0400 00377 0177 1363 00400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 26 Field 0 Variables BTS6120.plx 1364 .TITLE Field 0 Variables 1365 1366 1367 ; Page zero of field zero contains most of the runtime data for the monitor, 1368 ; including the saved state of the user (main memory) program. It is purposely 1369 ; NOT overlayed by any startup code so that it may also contain initialized 1370 ; variables, such as JMP/JMS vectors. Data in this page gets initialized 1371 ; automatically when the first phase of system initialization copies the EPROM 1372 ; to RAM. 1373 1374 ; These words contain the saved state of the main memory (aka user) 1375 ; program. The PC gets saved to location zero automatically by the 6120 1376 ; on any entry to control panel, and the rest get saved by the code around 1377 ; CPSAVE... 1378 00000 .ORG 0000 1379 00000 UPC: .BLOCK 1 ; program counter (saved by the hardware) 1380 00001 UAC: .BLOCK 1 ; accumulator 1381 00002 UFLAGS: .BLOCK 1 ; status (LINK, GT, IF, DF, etc) from GCF 1382 00003 UMQ: .BLOCK 1 ; MQ register 1383 00004 USP1: .BLOCK 1 ; 6120 stack pointer #1 1384 00005 USP2: .BLOCK 1 ; " " " #2 1385 00006 UIRPC: .BLOCK 1 ; program counter where IR was fetched from 1386 00007 UIR: .BLOCK 1 ; the last main memory instruction to be executed 1387 1388 ; Auto-index registers... 1389 00010 .ORG 0010 ; this must be at location 10 !!! 1390 00010 X1: .BLOCK 1 ; the first auto-index register 1391 00011 X2: .BLOCK 1 ; the second auto-index register 1392 00012 X3: .BLOCK 1 ; the third auto-index register 1393 00013 L: .BLOCK 1 ; the command line pointer 1394 1395 00020 .ORG 0020 ; don't put anything else in auto-index locations 1396 1397 ; Persistent settings - will be read from NVRAM if any exists - 1398 0020 FIRSTPSS=. 1399 00020 PARMAP: .BLOCK 10 ; unit number to partition map for eight OS/8 units 1400 00030 WIDTH: .BLOCK 1 ; the width of the terminal 1401 00031 LENGTH: .BLOCK 1 ; the number of lines on the screen 1402 00032 SCOPE: .BLOCK 1 ; 1 if DEL should backspace 1403 0033 LASTPSS=. 1404 ; - end of persistent settings 1405 1406 ; Extension ROM info 1407 00033 EXTFLAG: .BLOCK 1 ; 0=no ext. ROM, 1=OK, 2=Bad checksum, 3..=error code 1408 RAMBAS: .DATA -1 ; RAM disk starting offset - 1 in each field 00034 7777 1409 1410 ; Command parameters... 1411 00035 ADDR: .BLOCK 1 ; the current address 1412 00036 ADRFLD: .BLOCK 1 ; the field of this command 1413 00037 PNLMEM: .BLOCK 1 ; non-zero if ADDR/ADRFLD references panel memory 1414 00040 HIGH: .BLOCK 1 ; the high end of an address range 1415 00041 LOW: .BLOCK 1 ; the low end of an address range 1416 00042 HGHFLD: .BLOCK 1 ; the field of the high address 1417 00043 LOWFLD: .BLOCK 1 ; the field of the low address 1418 00044 VALUE: .BLOCK 1 ; the data word or value 1419 00045 NAME: .BLOCK 1 ; the name of this command 1420 00046 CHKSUM: .BLOCK 1 ; the checksum of memory or tape 1421 00047 SIMFLG: .BLOCK 1 ; non-zero if we're executing a single instruction 1422 00050 SAVCHR: .BLOCK 1 ; a place to save a character 1423 1424 ; Terminal parameters... 1425 00051 CTRLO: .BLOCK 1 ; non-zero if output is supressed 1426 00052 XOFF: .BLOCK 1 ; non-zero if output is suspended 1427 00053 HPOS: .BLOCK 1 ; the current horizontal position PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 27 Field 0 Variables BTS6120.plx 1428 00054 VPOS: .BLOCK 1 ; the current vertical position 1429 00055 IRMA: .BLOCK 1 ; the console flag timeout counter 1430 1431 ; Front panel data... 1432 00056 FPDTCT: .BLOCK 1 ; non-zero if a FP6120 is present 1433 00057 FNSTAT: .BLOCK 1 ; last known state of the function switches 1434 00060 BTSWCN: .BLOCK 1 ; number of times the BOOT switch was pushed 1435 00061 FPPGMM: .BLOCK 1 ; non-zero for FP "program" mode 1436 00062 FPPGMD: .BLOCK 1 ; program data for program mode 1437 1438 ; Parameters for the repeat command... 1439 00063 REPCNT: .BLOCK 1 ; the number of times to repeat 1440 00064 REPLOC: .BLOCK 1 ; the location to repeat from 1441 1442 ; Number I/O locations... 1443 00065 WORD: .BLOCK 1 ; the number being read or written 1444 00066 WORDH: .BLOCK 1 ; the high order bits of the last word read 1445 00067 COUNT: .BLOCK 1 ; the number of digits read or written 1446 00070 DIGITS: .BLOCK 1 ; counts digits for numeric input/output routines 1447 1448 ; Storage for RDDUMP, DDDUMP, RLLOAD and DLLOAD, RFRMAT, and DFRMAT... 1449 00071 RECSIZ: .BLOCK 1 ; disk (page, block) size 1450 00072 RECCNT: .BLOCK 1 ; number of records to dump 1451 00073 FMTCNT: .BLOCK 1 ; number of blocks/records processed by FORMAT 1452 0040 CPYSRC=HIGH ; source partition for PC command 1453 0041 CPYDST=LOW ; destination partition for PC command 1454 1455 ; Page zero vectors (to save literal space)... 1456 00074 7400 ZOUTCHR: OUTCHR ; type a single character 1457 00075 7063 ZTSPACE: TSPACE ; type a space 1458 00076 7131 ZBACKS: TBACKS ; type a backspace 1459 00077 6322 ZTOCT4: TOCT4 ; type an octal number 1460 00100 6352 ZTOCT4C: TOCT4C ; type an octal number followed by a CRLF 1461 00101 6355 ZTOCT4M: TOCT4M ; type an octal number, a CRLF, and goto RESTA 1462 00102 6347 ZTOCT4S: TOCT4S ; type an octal number followed by a space 1463 00103 6343 ZTOCT3: TOCT3 ; type a 3 digit octal number 1464 00104 6277 ZTDECNW: TDECNW ; type a decimal number 1465 00105 7077 ZTDOT: TDOT ; type a dot (".") 1466 00106 7104 ZCRLF: CRLF ; type a carriage return/line feed 1467 00107 6237 ZINLMES: INLMES ; type a string passed in-line 1468 00110 6102 ZSPACMP: SPACMP ; get the next non-blank command character 1469 00111 6104 ZSPACM0: SPACM0 ; get a non-blank character starting with the current 1470 00112 6132 ZBACKUP: BACKUP ; backup the command line pointer 1471 00113 6115 ZEOLTST: EOLTST ; test current character for end of line 1472 00114 6113 ZEOLNXT: EOLNXT ; test the next character for end of line 1473 00115 0475 ZGET: GET ; get the next character from the command line 1474 00116 6720 ZOCTNW: OCTNW ; scan an octal number 1475 00117 6441 ZRANGE: RANGE ; scan an address range (e.g. "0-7777") 1476 00120 6506 ZTSTADR: TSTADR ; compare the HIGH/HGHFLD to LOW/LOWFLD 1477 00121 6473 ZNXTADR: NXTADR ; increment ADDR/ADRFLD 1478 00122 1316 ZRDMEM: RDMEM ; read a word from main or panel memory 1479 00123 1342 ZDANDV: DANDV ; deposit (in memory) and verify 1480 00124 0400 ZRESTA: RESTA ; monitor restart vector 1481 00125 0453 ZCOMERR: COMERR ; report a command syntax error and restart 1482 00126 0465 ZERROR: ERROR ; print an error message and restart 1483 00127 4400 ZPUSHJ1: PUSHJ1 ; call a routine in field 1 and return to field 0 1484 1485 ; Page zero constants (to save literal space)... 1486 00130 0177 ZK177: 177 ; used everywhere as a mask for ASCII characters 1487 00131 0070 ZK70: 70 ; used as a mask for data/instruction fields 1488 00132 0007 ZK7: 7 ; yet another mask 1489 00133 7740 ZMSPACE: -" " ; an ASCII space character (or the negative there of) 1490 00134 7600 ZM128: -128. ; record size of RAM disk 1491 0134 ZK7600=ZM128 1492 00135 7400 ZM256: -256. ; record size of IDE disk PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 28 Field 0 Variables BTS6120.plx 1493 0135 ZK7400=ZM256 1494 00136 0025 ZRDPAGE: RDPAGE ; current RAM disk page number in field 1 1495 00137 0021 ZDKRBN: DKRBN ; current IDE disk block number in field 1 1496 1497 ; Local storage for INCHWL... 1498 00140 CMDLEN: .BLOCK 1 ; the length of the current line 1499 00141 PROMPT: .BLOCK 1 ; the prompting character 1500 1501 ; The software stack occupies all of the rest of page zero. 1502 00142 STKSAV: .BLOCK 1 ; the last monitor SP is saved here by CONTINUE 1503 0177 STACK=0177 1504 0034 STKLEN=STACK-. ; Length of the stack (if anybody cares) 1505 00143 .BLOCK STKLEN 1506 1507 1508 ; Page one of field zero contains the second phase system initialization 1509 ; code, and it's over written by the command line buffer and break point 1510 ; tables after we're running. 1511 00200 .ORG 0200 1512 1513 ; The PDP2HEX program stores a checksum of ROM field 0 in location 00200, 1514 ; and we have to reserve space for it here so it doesn't get overwritten by 1515 ; any of our data. See the code at ROMCK0: for more discussion. 1516 00200 .BLOCK 1 1517 1518 ; Breakpoint storage... 1519 0010 MAXBPT=8. ; maximum number of breakpoints 1520 00201 BPTADR: .BLOCK MAXBPT ; address assigned to each breakpoint 1521 00211 BPTFLD: .BLOCK MAXBPT ; field of the breakpoint 1522 00221 BPTDAT: .BLOCK MAXBPT ; original data at the breakpoint 1523 0210 BPTEND=BPTADR+MAXBPT-1 ; end of the breakpoint address table 1524 1525 ; The command line buffer for INCHWL occupies all that remains of page one... 1526 0147 MAXCMD=0400-. ; space available for the command buffer 1527 00231 CMDBUF: .BLOCK MAXCMD ; and the actual command buffer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 29 Monitor Main Loop BTS6120.plx 1528 .TITLE Monitor Main Loop 1529 1530 00400 .PAGE 2 1531 1532 ; This routine will read commands from the terminal and execute them. It 1533 ; can be entered at RESTA to restart after a control-C or a fatal error, and 1534 ; at BOOTS after completion of a normal command... 1535 ; HOOK: Monitor reentry 1536 00400 7000 RESTA: NOP 1537 00401 7000 NOP 1538 00402 7000 NOP 1539 00403 6276 SPD ; Ensure that CP memory is always selected 1540 00404 6435 RLOF ; The RUN LED is off while we're here 1541 00405 7200 CLA ; And be sure the AC is cleared 1542 00406 1377 TAD [STACK] ; Point to the stack 1543 00407 6217 LSP1 ; Clean up the stack pointer 1544 00410 6205 .PUSHJ @ZCRLF ; Be sure the terminal is ready 00411 5506 1545 1546 ; Read another command line... 1547 00412 7200 BOOTS: CLA ; ... 1548 00413 1376 TAD [">"] ; Point to the prompt 1549 00414 6205 .PUSHJ @[INCHWL] ; Initialize the line input routine 00415 5775 1550 00416 6205 BOOTS0: .PUSHJ @[SWSCAN] ; Scan the switches while we're waiting 00417 5774 1551 00420 6205 .PUSHJ @[INCHW1] ; Read another character into the line 00421 5773 1552 00422 7650 SNA CLA ; EOL? 1553 00423 5216 JMP BOOTS0 ; Nope - keep reading 1554 00424 3063 DCA REPCNT ; Clear the repeat counter initially 1555 1556 ; Execute the next command... 1557 00425 6205 BOOTS1: .PUSHJ @[NAMENW] ; First identify a command 00426 5772 1558 00427 1045 TAD NAME ; Get the name we read 1559 00430 7650 SNA CLA ; Is this a null command ?? 1560 00431 5235 JMP BOOTS2 ; Yes -- just ignore it 1561 00432 1371 TAD [CMDTBL-1] ; Then point to the list of commands 1562 00433 6205 .PUSHJ @[MATCH] ; And look it up 00434 5770 1563 1564 ; See if there are more commands on this line... 1565 00435 1013 BOOTS2: TAD L ; Get the pointer to the last character 1566 00436 3065 DCA WORD ; And save it in a non-autoindex location 1567 00437 1465 TAD @WORD ; Get the last character we saw 1568 00440 1367 TAD [-073] ; Was it a command seperator ?? 1569 00441 7650 SNA CLA ; ???? 1570 00442 5225 JMP BOOTS1 ; Yes -- go execute another command 1571 1572 ; See if this command needs to be repeated... 1573 00443 7240 STA ; Load the AC with -1 1574 00444 1063 TAD REPCNT ; And add to the repeat counter 1575 00445 7510 SPA ; Is the counter positive ?? 1576 00446 5212 JMP BOOTS ; No -- go read anothter line 1577 00447 3063 DCA REPCNT ; Yes -- save the new count 1578 00450 1064 TAD REPLOC ; And get the location to start from 1579 00451 3013 DCA L ; Backup the command scanner 1580 00452 5225 JMP BOOTS1 ; Then go execute this command again PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 30 Command Error Processing BTS6120.plx 1581 .TITLE Command Error Processing 1582 1583 1584 ; This routine is called when a syntax error is found in the command and it 1585 ; echo the part of the command which has already been scanned inside question 1586 ; marks (very much like TOPS-10 used to do!). After that, the monitor is 1587 ; restarted (i.e. the stack is cleaned up and another prompt issued). 1588 00453 7200 COMERR: CLA ; Ignore the contents of the AC 1589 00454 3413 DCA @L ; And mark the end of what was actually scanned 1590 00455 6205 .PUSHJ @[TQUEST] ; Type the first question mark 00456 5766 1591 00457 1365 TAD [CMDBUF-1] ; And point to the command line 1592 00460 6205 .PUSHJ @[TASCIZ] ; Echo that 00461 5764 1593 00462 6205 .PUSHJ @[TQUEST] ; Then type another question 00463 5766 1594 00464 5200 JMP RESTA ; Go restart the monitor 1595 1596 1597 ; This routine prints an error message and then restarts the monitor. Unlike 1598 ; nearly every other routine in the monitor this one is called via a JMS 1599 ; instruction rather than a .PUSHJ, and that so that the address of the error 1600 ; message can be passed in line, in the word after the JMS. 1601 ; 1602 ; CALL: 1603 ; JMS @ZERROR 1604 ;
1605 00465 0000 ERROR: 0 ; enter here with a JMS 1606 00466 7200 CLA ; the AC is unknown here 1607 00467 6205 .PUSHJ @[TQUEST] ; always type a question mark 00470 5766 1608 00471 1665 TAD @ERROR ; pick up the address of the message 1609 00472 6205 .PUSHJ @[OUTSTR] ; and type that out too 00473 5763 1610 00474 5524 JMP @ZRESTA ; restart the monitor and read another command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 31 Get Next Command Character BTS6120.plx 1611 .TITLE Get Next Command Character 1612 1613 1614 ; This routine will get the next character from the command line. If the 1615 ; character is lower case, it is folded to upper case. If the character is a 1616 ; TAB, it is converted to a space. And, if the character is ";" or "!" (the 1617 ; start of a comment) it is converted to zero (end of line). Finally, the 1618 ; character is returned in both the AC and location SAVCHR. 1619 00475 7200 GET: CLA ; Be sure the AC is safe to use 1620 00476 1413 TAD @L ; Get another character from the line 1621 00477 1362 TAD [-"A"-40] ; Compare this character to lower case A 1622 00500 7500 SMA ; ??? 1623 00501 5315 JMP GET1 ; It might be a lower case letter 1624 1625 ; The character is not lower case -- check for a TAB, ; or !... 1626 00502 1361 TAD ["A"+40-CHTAB] ; Is this a tab character ?? 1627 00503 7450 SNA ; ??? 1628 00504 1360 TAD [" "-CHTAB] ; Yes -- convert it to a space 1629 00505 1357 TAD [CHTAB-"!"] ; No -- Is it a ! character ?? 1630 00506 7450 SNA ; ??? 1631 00507 1356 TAD [-"!"] ; Yes -- Convert it to a null 1632 00510 1355 TAD ["!"-073] ; Last chance -- is it a ; ?? 1633 00511 7450 SNA ; ??? 1634 00512 1367 TAD [-073] ; Yes -- convert that to zero too 1635 00513 1354 TAD [073] ; No -- restore the original character 1636 00514 5321 JMP GET2 ; Then store the character and return 1637 1638 ; Here if the character might be lower case... 1639 00515 1353 GET1: TAD ["A"-"Z"] ; Compare to the other end of the range 1640 00516 7550 SPA SNA ; ??? 1641 00517 1352 TAD [-40] ; It's lower case -- convert to upper 1642 00520 1351 TAD ["Z"+40] ; Restore the correct character 1643 1644 ; Store the character and return... 1645 00521 3050 GET2: DCA SAVCHR ; Remember this character 1646 00522 1050 TAD SAVCHR ; And also return it in the AC 1647 00523 6225 .POPJ ; And that's it 1648 00551 0172 00552 7740 00553 7747 00554 0073 00555 7746 00556 7737 00557 7750 00560 0027 00561 0130 00562 7637 00563 6200 00564 6246 00565 0230 00566 7066 00567 7705 00570 6642 00571 3177 00572 6600 00573 7210 00574 5621 00575 7200 00576 0076 00577 0177 1649 00600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 32 RP Command -- Repeat BTS6120.plx 1650 .TITLE RP Command -- Repeat 1651 1652 1653 ; This command allows the rest of the command line to be repeated, and it 1654 ; accepts an optional argument which specifes the number of times to repeat, 1655 ; in decimal. The range for this argument is 1 to 2047 and if it is omitted, 1656 ; it defaults to 2047. Note that repeat commands may not be nested; a repeat 1657 ; command will cancel any previous repeat on the same command line. Any error 1658 ; or a control-C will terminate the repetition prematurely. 1659 00600 6205 REPEAT: .PUSHJ @ZSPACMP ; Get the next character 00601 5510 1660 00602 7650 SNA CLA ; Is it the end of the command ?? 1661 00603 5215 JMP REPEA1 ; Yes -- use the default count 1662 00604 6205 .PUSHJ @ZBACKUP ; No -- backup the scanner 00605 5512 1663 00606 6205 .PUSHJ @[DECNW] ; Then read a decimal number 00607 5777 1664 00610 6205 .PUSHJ @ZEOLTST ; Then test for the end of the line 00611 5513 1665 1666 ; Set up the repeat counter... 1667 00612 7240 STA ; Subtract one from the user's 1668 00613 1065 TAD WORD ; argument... 1669 00614 7410 SKP ; ... 1670 00615 7350 REPEA1: NL3777 ; If there's no argument, use 2047 1671 00616 3063 DCA REPCNT ; Set the repeat counter 1672 1673 ; Set up the repeat pointer... 1674 00617 1013 TAD L ; Get the current line pointer 1675 00620 3064 DCA REPLOC ; Remember where to start from 1676 00621 1464 TAD @REPLOC ; Then examine the current character 1677 00622 7650 SNA CLA ; Is the repeat the last command on the line ?? 1678 00623 3063 DCA REPCNT ; Yes -- this is all pointless after all 1679 00624 6225 .POPJ ; Then proceed with the next command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 33 TW, TP, SC Commands - Set Terminal Width, Page and Scope BTS6120.plx 1680 .TITLE TW, TP, SC Commands - Set Terminal Width, Page and Scope 1681 1682 1683 ; The TW command sets the terminal screen width to the value of its argument, 1684 ; which is a _decimal_ number. Screen widths are limited to the range 32..255. 1685 00625 6205 TWCOM: .PUSHJ @[DECNW] ; read a decimal operand again 00626 5777 1686 00627 6205 .PUSHJ @ZEOLTST ; then check for the end of the line 00630 5513 1687 00631 1065 TAD WORD ; get the desired width 1688 00632 7450 SNA ; is it zero ?? 1689 00633 5243 JMP TWCOM1 ; yes -- that disables automatic returns 1690 00634 1376 TAD [-32.] ; compare it to 32 1691 00635 7510 SPA ; is it at least 32 ?? 1692 00636 5246 JMP TFILV ; no -- ?ILLEGAL VALUE 1693 00637 1375 TAD [32.-255.] ; now compare it to 255 1694 00640 7540 SMA SZA ; it can't be bigger than that 1695 00641 5246 JMP TFILV ; but it is... 1696 00642 1374 TAD [255.] ; restore the original number 1697 00643 3030 TWCOM1: DCA WIDTH ; and set the terminal width 1698 00644 6222 TWCOM2: CIF 2 1699 00645 5773 JMP @[WRPSS] ; store it in NVRAM if it exists 1700 ; and we're all done 1701 1702 ; Here if the parameter value is illegal... 1703 00646 4526 TFILV: JMS @ZERROR ; yes -- it isn't legal 1704 00647 3430 ERRILV ; ?ILLEGAL VALUE 1705 1706 ; The TP command sets the terminal page size to the value of its argument, 1707 ; in _decimal_. Page sizes may range from 12 to 48, or zero. A value of zero 1708 ; disables the automatic XOFF function completely. 1709 00650 6205 TPCOM: .PUSHJ @[DECNW] ; Read a decimal operand 00651 5777 1710 00652 6205 .PUSHJ @ZEOLTST ; And check for the end of the line 00653 5513 1711 00654 1065 TAD WORD ; Get the value he gave 1712 00655 7450 SNA ; Is it zero ?? 1713 00656 5266 JMP TPCOM1 ; Yes -- that is legal (to disable) 1714 00657 1372 TAD [-12.] ; Compare it to 12 lines 1715 00660 7510 SPA ; We have to have at least that many 1716 00661 5246 JMP TFILV ; No -- ?ILLEGAL VALUE 1717 00662 1376 TAD [16.-48.] ; Then compare it to 48 1718 00663 7540 SMA SZA ; Is it more than that ?? 1719 00664 5246 JMP TFILV ; Yes -- that won't work, either 1720 00665 1371 TAD [48.] ; Restore the original number 1721 00666 3031 TPCOM1: DCA LENGTH ; And set the new terminal length 1722 00667 5244 JMP TWCOM2 1723 1724 ; The SC command sets the SCOPE flag to its operand. When non-zero, the 1725 ; line input command will respond to a DEL with a destructive backspace 1726 ; instead of the default echo. 1727 00670 6205 SCCOM: .PUSHJ @[DECNW] ; Read a decimal operand 00671 5777 1728 00672 6205 .PUSHJ @ZEOLTST ; And check for the end of the line 00673 5513 1729 00674 1065 TAD WORD ; Get the value he gave 1730 00675 3032 DCA SCOPE 1731 00676 5244 JMP TWCOM2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 34 VE Command - Show System Name and Version BTS6120.plx 1732 .TITLE VE Command - Show System Name and Version 1733 1734 1735 ; This routine will type the name and version of the monitor. It is called 1736 ; at startup, and by the VE command. 1737 00677 6205 VECOM: .PUSHJ @ZEOLNXT ; enter here for the VE command 00700 5514 1738 00701 4507 HELLO: JMS @ZINLMES ; type out the name of the system 1739 00702 4117 SYSNM1 ; ... 1740 00703 1370 TAD [VERSION] ; get the present edit level 1741 00704 6205 .PUSHJ @ZTOCT3 ; type that in octal 00705 5503 1742 00706 4507 JMS @ZINLMES ; say 1743 00707 4136 SYSNM2 ; "Checksum " 1744 00710 1767 TAD @[ROMCK0] ; get the checksum of ROM field 0 1745 00711 6205 .PUSHJ @ZTOCT4S ; type that and a space 00712 5502 1746 00713 6211 CDF 1 ; then do the same for ROM field 1 1747 00714 1767 TAD @[ROMCK1] ; ... 1748 00715 6201 CDF 0 ; ... 1749 00716 6205 .PUSHJ @ZTOCT4S ; this time end with a CRLF 00717 5502 1750 00720 6221 CDF 2 ; and do the same for ROM field 2 1751 00721 1767 TAD @[ROMCK2] ; ... 1752 00722 6201 CDF 0 ; ... 1753 00723 6205 .PUSHJ @ZTOCT4S ; this time end with a CRLF 00724 5502 1754 00725 4507 JMS @ZINLMES ; finally, type the system date 1755 00726 4146 SYSNM3 ; ... 1756 00727 6205 .PUSHJ @ZCRLF ; finish that line 00730 5506 1757 00731 4507 JMS @ZINLMES ; then type the copyright notice 1758 00732 4164 SYSCRN ; ... 1759 00733 6205 .PUSHJ @ZCRLF 00734 5506 1760 00735 5506 JMP @ZCRLF ; finish that line and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 35 H Command - Show Monitor Help BTS6120.plx 1761 .TITLE H Command - Show Monitor Help 1762 1763 ; The H command generates a simple list of all monitor commands and a 1764 ; brief, one line, help message for each. The whole function is driven 1765 ; by a table of help messages stored in field one - this table contains 1766 ; a list of pointers and each pointer points to the packed ASCII text of 1767 ; a single line of help. We simply print each line and add a CRLF at the 1768 ; end. It's done this way (as a table of lines) rather than as a single, 1769 ; huge, string with embedded CRLFs because the automatic XOFF (i.e. terminal 1770 ; page) processing is done via the CRLF routine. Embedded CRLFs wouldn't 1771 ; automatically XOFF, and so most of the text would scroll right off the 1772 ; top of the CRT. 1773 00736 6205 HELP: .PUSHJ @ZEOLTST ; no arguments are allowed 00737 5513 1774 00740 1366 TAD [HLPLST-1] ; point to the list of help messages 1775 00741 3012 DCA X3 ; in an auto index register 1776 00742 6211 HELP1: CDF 1 ; the help text and table lives in field 1 1777 00743 1412 TAD @X3 ; get the next help message 1778 00744 6201 CDF 0 ; back to our field 1779 00745 7450 SNA ; end of list? 1780 00746 6225 .POPJ ; yes - we can quit now 1781 00747 6205 .PUSHJ @[OUTSTR] ; nope - type this string 00750 5765 1782 00751 6205 .PUSHJ @ZCRLF ; and finish the line 00752 5506 1783 00753 5342 JMP HELP1 ; keep typing until we run out of strings 1784 00765 6200 00766 4364 00767 0200 00770 0271 00771 0060 00772 7764 00773 0243 00774 0377 00775 7441 00776 7740 00777 6662 1785 01000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 36 E and EP Commands -- Examine Main Memory or Panel Memory BTS6120.plx 1786 .TITLE E and EP Commands -- Examine Main Memory or Panel Memory 1787 1788 1789 ; The E command allows the user to examine the contents of memory in octal, 1790 ; either one word at a time or an entire range of addresses. In the latter 1791 ; case a memory dump is printed with eight PDP-8 words per line. It accepts 1792 ; several forms of operands, for example: 1793 ; 1794 ; >E 1234 -> Examine location 1234 in the data field 1795 ; >E 01234 -> Examime location 1234 of field zero 1796 ; >E 41234 -> Examine location 1234, field 4 1797 ; >E 71000-2000 -> Examine locations 1000 through 2000, field 7 1798 ; >E 50000-77777 -> Examine location 0, field 5 thru 7777, field 7 1799 ; 1800 ; The EP command is identical to E, except that panel memory is examined 1801 ; rather than main memory. 1802 1803 ; Enter here for the EP command... 1804 01000 7240 EPMEM: STA ; set the PNLMEM flag 1805 01001 7410 SKP ; fall into the regular code 1806 ; Enter here for the E command... 1807 01002 7200 EMEM: CLA ; clear the PNLMEM flag 1808 01003 3037 DCA PNLMEM ; to reference main memory 1809 1810 ; Both forms join up here... 1811 01004 6205 EMEM0: .PUSHJ @ZRANGE ; go read an address range 01005 5517 1812 01006 7420 SNL ; was there just one address ??? 1813 01007 5242 JMP EONE ; yes -- just examine one location 1814 1815 ; Fix up the address range for multiple word examines... 1816 01010 1041 TAD LOW ; get the low boundry 1817 01011 0377 AND [7770] ; round it down to a multiple of 8 1818 01012 3035 DCA ADDR ; then it becomes the starting address 1819 01013 1040 TAD HIGH ; get the ending address 1820 01014 0377 AND [7770] ; round it up to a multiple of 8 1821 01015 1132 TAD ZK7 ; ... 1822 01016 3040 DCA HIGH ; and remember the last address to process 1823 1824 ; Type out lines of 8 memory locations... 1825 01017 6205 EMEM1: .PUSHJ @[TADDR] ; type out the address of the next word 01020 5776 1826 01021 6205 EMEM2: .PUSHJ @ZRDMEM ; go read a word from main memory 01022 5522 1827 01023 6205 .PUSHJ @ZTOCT4S ; type the word in octal 01024 5502 1828 01025 6205 .PUSHJ @ZTSTADR ; have we done all the locations ?? 01026 5520 1829 01027 7430 SZL ; are we there yet ??? 1830 01030 5244 JMP EMEM3 ; yes -- finish the line and return 1831 01031 6205 .PUSHJ @ZNXTADR ; no -- increment to the next address 01032 5521 1832 01033 1035 TAD ADDR ; get the current address 1833 01034 0132 AND ZK7 ; is it a multiple of 8 ?? 1834 01035 7640 SZA CLA ; ??? 1835 01036 5221 JMP EMEM2 ; no -- keep typing 1836 01037 6205 .PUSHJ @ZCRLF ; yes -- start on a new line 01040 5506 1837 01041 5217 JMP EMEM1 ; and type the next address 1838 1839 ; Here to examine a single memory location... 1840 01042 6205 EONE: .PUSHJ @[TMEM] ; type out the contents of memory 01043 5775 1841 ; and fall into the next range 1842 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 37 E and EP Commands -- Examine Main Memory or Panel Memory BTS6120.plx 1843 ; Here when we've finished examining one range of addresses... 1844 01044 6205 EMEM3: .PUSHJ @ZCRLF ; finish the current line 01045 5506 1845 01046 6205 .PUSHJ @ZBACKUP ; backup the command line pointer 01047 5512 1846 01050 6205 .PUSHJ @ZSPACMP ; ... and get the next character 01051 5510 1847 01052 7450 SNA ; is it the end of the line ?? 1848 01053 6225 .POPJ ; yes -- just stop now 1849 01054 1374 TAD [-","] ; no -- check for a comma 1850 01055 7640 SZA CLA ; ???? 1851 01056 5525 JMP @ZCOMERR ; this isn't legal 1852 01057 5204 JMP EMEM0 ; yes -- do another operand 1853 1854 ; This routine will type the address and contents of the memory location 1855 ; indicated by registers ADDR and ADRFLD. 1856 01060 6205 TMEM: .PUSHJ @[TADDR] ; first type the address 01061 5776 1857 01062 6205 .PUSHJ @ZRDMEM ; then load the indicated word 01063 5522 1858 01064 5502 JMP @ZTOCT4S ; type it out and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 38 D and DP Commands -- Deposit in Main Memory or Panel Memory BTS6120.plx 1859 .TITLE D and DP Commands -- Deposit in Main Memory or Panel Memory 1860 1861 1862 ; The D command allows the user to deposit one or more words in memory. The 1863 ; general format is: 1864 ; 1865 ; >D 60123 4567 -> Deposit 4567 into location 0123, field 6 1866 ; >D 40000 1,2,3,4 -> Deposit 0001 into location 0, field 4, and 0002 1867 ; into location 1, field 4, and 0003 into location 1868 ; 2, etc... 1869 ; 1870 ; The DP command is identical to D, except that panel memory is chaged rather 1871 ; than main memory. WARNING - there is no protection against changing the 1872 ; monitor when using this command, so it's up to the user to make sure the 1873 ; changes don't corrupt something important! 1874 1875 ; Enter here for the DP command... 1876 01065 7240 DPMEM: STA ; set the PNLMEM flag 1877 01066 7410 SKP ; fall into the regular code 1878 ; Enter here for the D command... 1879 01067 7200 DMEM: CLA ; clear the PNLMEM flag 1880 01070 3037 DCA PNLMEM ; to reference main memory 1881 1882 ; Both forms join up here... 1883 01071 6205 .PUSHJ @[RDADDR] ; Then read an address 01072 5773 1884 01073 6205 .PUSHJ @[SPATST] ; the next character has to be a space 01074 5772 1885 1886 ; Read words of data and deposit them... 1887 01075 6205 DMEM1: .PUSHJ @ZOCTNW ; read an octal operand 01076 5516 1888 01077 1065 TAD WORD ; get the data we found 1889 01100 6205 .PUSHJ @ZDANDV ; write and verify it 01101 5523 1890 01102 6205 .PUSHJ @ZNXTADR ; advance to the next address 01103 5521 1891 01104 6205 .PUSHJ @ZSPACM0 ; get the break character from OCTNW 01105 5511 1892 01106 7450 SNA ; was it the end of the line ?? 1893 01107 6225 .POPJ ; yes, we're done... 1894 01110 1374 TAD [-","] ; no - it has to be a comma otherwise 1895 01111 7640 SZA CLA ; ???? 1896 01112 5525 JMP @ZCOMERR ; bad command 1897 01113 5275 JMP DMEM1 ; go read and deposit another word PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 39 ER and DR Commands - Examine and Deposit in Registers BTS6120.plx 1898 .TITLE ER and DR Commands - Examine and Deposit in Registers 1899 1900 1901 ; The ER command examines either a single register, when the register name 1902 ; is given as an argument, or all registers when no argument is given. For 1903 ; example: 1904 ; 1905 ; >ER AC - examine the AC 1906 ; >ER PC - examine the PC 1907 ; >ER - print all registers 1908 ; 1909 01114 6205 EREG: .PUSHJ @ZSPACMP ; get the next non-space character 01115 5510 1910 01116 7650 SNA CLA ; is it the end of line? 1911 01117 5771 JMP @[REGLSC] ; yes - type all registers and return 1912 01120 6205 .PUSHJ @ZBACKUP ; nope - backup the command scanner 01121 5512 1913 01122 6205 .PUSHJ @[NAMENW] ; and go read the register name 01123 5770 1914 01124 6205 .PUSHJ @ZEOLNXT ; now we have to be at the end of line 01125 5514 1915 01126 1367 TAD [ENAMES-1] ; point to the name table 1916 01127 6205 .PUSHJ @[MATCH] ; find it and call a routine to print 01130 5766 1917 01131 5506 JMP @ZCRLF ; finish the line and we're done 1918 1919 ; The DR command deposits a value in a register, and both a register name and 1920 ; an octal value are required arguments. For example: 1921 ; 1922 ; >DR AC 7777 - set the AC to 7777 1923 ; >DR SR 3345 - set the switch register to 3345 1924 ; 1925 01132 6205 DREG: .PUSHJ @[NAMENW] ; get the register name 01133 5770 1926 01134 6205 .PUSHJ @[SPANXT] ; the terminator has to be a space 01135 5765 1927 01136 6205 .PUSHJ @ZOCTNW ; read an octal number to deposit 01137 5516 1928 01140 6205 .PUSHJ @ZEOLTST ; followed by the end of the line 01141 5513 1929 01142 1364 TAD [DNAMES-1] ; point to the list of deposit names 1930 01143 5766 JMP @[MATCH] ; call the right routine and we're done 1931 01164 3357 01165 6122 01166 6642 01167 3343 01170 6600 01171 1240 01172 6124 01173 6416 01174 7724 01175 1060 01176 6400 01177 7770 1932 01200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 40 Deposit in Registers BTS6120.plx 1933 .TITLE Deposit in Registers 1934 1935 1936 ; Here to deposit in the AC... 1937 01200 1065 DAC: TAD WORD ; Get his value 1938 01201 3001 DCA UAC ; And change the AC 1939 01202 6225 .POPJ ; Then that's all 1940 1941 ; Here to deposit in the PC... 1942 01203 1065 DPC: TAD WORD ; The same old routine... 1943 01204 3000 DCA UPC ; ... 1944 01205 5777 JMP @[EXMEM] ; sync the display with the new PC 1945 1946 ; Here to deposit in the MQ... 1947 01206 1065 DMQ: TAD WORD ; ... 1948 01207 3003 DCA UMQ ; ... 1949 01210 6225 .POPJ ; ... 1950 1951 ; Here to deposit in the PS... 1952 01211 1065 DPS: TAD WORD ; ... 1953 01212 0376 AND [6277] ; only these bits can actually change 1954 01213 7421 MQL ; save the new value for a minute 1955 01214 1002 TAD UFLAGS ; get the current status 1956 01215 0375 AND [1500] ; clear the complementary bits 1957 01216 7501 MQA ; or everything together 1958 01217 3002 DCA UFLAGS ; and update the PS 1959 01220 5777 JMP @[EXMEM] ; sync the display with the new IF 1960 1961 ; Here to deposit in the switch register... 1962 01221 1065 DSR: TAD WORD ; ... 1963 01222 6246 WSR ; Load the switch register 1964 01223 6225 .POPJ ; Then that's all 1965 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 41 Examine Registers BTS6120.plx 1966 .TITLE Examine Registers 1967 1968 1969 ; This routine is called to type out all the important internal registers. 1970 ; It is used by the ER, and SI commands, and after breakpoints, traps and 1971 ; halts. 1972 01224 7200 REGLST: CLA ; be sure the AC is cleared 1973 01225 6205 .PUSHJ TYPEPC ; type the PC first 01226 5255 1974 01227 6205 .PUSHJ TYPEPS ; then the LINK 01230 5265 1975 01231 6205 .PUSHJ TYPEAC ; then the AC 01232 5252 1976 01233 6205 .PUSHJ TYPEMQ ; then the MQ 01234 5260 1977 01235 6205 .PUSHJ TYPSP1 ; user stack pointer 1 01236 5270 1978 01237 5273 JMP TYPSP2 ; and finally stack pointer 2 1979 1980 ; The same as REGLST, but with a carriage return added... 1981 01240 6205 REGLSC: .PUSHJ REGLST ; first type the registers 01241 5224 1982 01242 5506 JMP @ZCRLF ; type the carriage return and we're done 1983 1984 ; This routine types a register name followed by an octal register value. 1985 ; The latter is passed in the AC, and the register name is passed inline. 1986 01243 0000 TYPRG4: 0 ; enter here with a JMS instruction 1987 01244 3044 DCA VALUE ; save the register contents for a moment 1988 01245 1643 TAD @TYPRG4 ; and get the address of the register name 1989 01246 6205 .PUSHJ @[OUTSTR] ; type that 01247 5774 1990 01250 1044 TAD VALUE ; get the contents of the register 1991 01251 5502 JMP @ZTOCT4S ; type that in octal and leave a blank 1992 1993 ; This routine will type the last user AC contents... 1994 01252 1001 TYPEAC: TAD UAC ; get the contents of the register 1995 01253 4243 JMS TYPRG4 ; type it and return 1996 01254 3711 ACNAME ; "AC>" 1997 1998 ; This routine will type the last user PC... 1999 01255 1000 TYPEPC: TAD UPC ; the same old routine... 2000 01256 4243 JMS TYPRG4 ; ... 2001 01257 3714 PCNAME ; "PC>" 2002 2003 ; This routine will type the last user MQ contents... 2004 01260 1003 TYPEMQ: TAD UMQ ; ... 2005 01261 4243 JMS TYPRG4 ; ... 2006 01262 3717 MQNAME ; "MQ>" 2007 2008 ; This routine will type the last instruction executed... 2009 01263 6222 TYPEIR: CIF 2 2010 01264 5773 JMP @[XTYPIR] 2011 2012 ; This routine will type the current interrupt flags... 2013 01265 1002 TYPEPS: TAD UFLAGS ; get the flags 2014 01266 4243 JMS TYPRG4 ; ... 2015 01267 3730 PSNAME ; "PS>" 2016 2017 ; This routine will type the 6120 stack pointer #1... 2018 01270 1004 TYPSP1: TAD USP1 ; ... 2019 01271 4243 JMS TYPRG4 ; ... 2020 01272 3733 SP1NAM ; "SP1>" 2021 2022 ; This routine will type the 6120 stack pointer #2... 2023 01273 1005 TYPSP2: TAD USP2 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 42 Examine Registers BTS6120.plx 2024 01274 4243 JMS TYPRG4 ; ... 2025 01275 3737 SP2NAM ; "SP2>" 2026 2027 ; This routine will type the current switch register contents... 2028 01276 7604 TYPESR: LAS ; actually read the switch register 2029 01277 4243 JMS TYPRG4 ; ... 2030 01300 3725 SRNAME ; "SR>" PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 43 Read and Write Memory BTS6120.plx 2031 .TITLE Read and Write Memory 2032 2033 2034 ; This routine will change the current data field to the field indicated in 2035 ; location ADRFLD. It's normally used by commands that read or write memory, 2036 ; such as Examine, Deposit, etc. Remember that on the 6120 the EMA works in 2037 ; panel memory as well, so don't forget to change back to field zero after 2038 ; you're done! 2039 01301 7200 CFIELD: CLA ; ... 2040 01302 1036 TAD ADRFLD ; get the desired field number 2041 01303 0131 AND ZK70 ; just in case! 2042 01304 1372 TAD [CDF 0] ; and make a CDF instruction 2043 01305 3306 DCA .+1 ; store that in memory 2044 01306 0000 0 ; isn't self manipulation wonderful? 2045 01307 6225 .POPJ ; that's all 2046 2047 ; This routine will set or clear the panel data flag according to the state 2048 ; of the PNLMEM flag. If PNLMEM is non-zero, the panel data flag is set and 2049 ; commands that access memory (e.g. Examine, Deposit, etc) access panel memory 2050 ; instead. If PNLMEM is zero, then the panel data flag is cleared and these 2051 ; commands access main memory. 2052 01310 7200 CPANEL: CLA ; don't expect anything from the caller 2053 01311 6276 SPD ; assume we're referencing panel memory 2054 01312 1037 TAD PNLMEM ; but get the flag to be sure 2055 01313 7650 SNA CLA ; non-zero means access panel memory 2056 01314 6266 CPD ; we were wrong - use main memory instead 2057 01315 6225 .POPJ ; and we're done 2058 2059 ; This short routine returns, in the AC and memory location VALUE, the 2060 ; contents of the memory location addressed by ADDR and ADRFLD. If PNLMEM is 2061 ; non-zero it reads panel memory to get the data; otherwise it reads main 2062 ; memory... 2063 01316 6205 RDMEM: .PUSHJ CFIELD ; first select the proper field 01317 5301 2064 01320 6205 .PUSHJ CPANEL ; then select main memory or panel memory 01321 5310 2065 01322 1435 TAD @ADDR ; load the data 2066 01323 3044 DCA VALUE ; save the contents in VALUE 2067 01324 1044 TAD VALUE ; and also return it in the AC 2068 01325 6276 SPD ; back to panel memory 2069 01326 6201 CDF 0 ; and back to the monitor's field 2070 01327 6225 .POPJ ; that's all there is 2071 2072 ; This routine will deposit the contents of the AC into the memory location 2073 ; specified by ADRFLD, ADDR and PNLMEM. It's the complement of RDMEM... 2074 01330 3044 WRMEM: DCA VALUE ; save the number to deposit 2075 01331 6205 .PUSHJ CFIELD ; be sure we're in the right field 01332 5301 2076 01333 6205 .PUSHJ CPANEL ; and the right memory space (panel vs main) 01334 5310 2077 01335 1044 TAD VALUE ; get the value back again 2078 01336 3435 DCA @ADDR ; store the data 2079 01337 6276 SPD ; back to panel memory 2080 01340 6201 CDF 0 ; and the monitor's data field 2081 01341 6225 .POPJ ; and return 2082 2083 ; This routine is just like WRMEM, except that it will read back the value 2084 ; deposited and verify that it is, in fact, correct! If it isn't (i.e. there's 2085 ; no memory at that address or the memory there isn't working) a ?MEM ERR 2086 ; message is generated and this command is aborted. 2087 01342 3367 DANDV: DCA GOOD ; save the original, good, value 2088 01343 1367 TAD GOOD ; ... 2089 01344 6205 .PUSHJ WRMEM ; store it 01345 5330 2090 01346 6205 .PUSHJ RDMEM ; read it back PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 44 Read and Write Memory BTS6120.plx 01347 5316 2091 01350 7041 CIA ; make what we read negative 2092 01351 1367 TAD GOOD ; and compare it to the desired value 2093 01352 7650 SNA CLA ; did they match ?? 2094 01353 6225 .POPJ ; yes -- this memory is ok 2095 2096 ; Type a "?MEM ERR AT faaaa ..." message 2097 01354 4507 JMS @ZINLMES ; type out the first part of the message 2098 01355 3413 MEMMSG ; ... 2099 01356 6205 .PUSHJ @[TADDR] ; then type the address of the error 01357 5771 2100 01360 1367 TAD GOOD ; get the expected value 2101 01361 6205 .PUSHJ @ZTOCT4S ; type that out first 01362 5502 2102 01363 6205 .PUSHJ @ZRDMEM ; read what we actually get from memory 01364 5522 2103 01365 6205 .PUSHJ @ZTOCT4M ; then type that with a CRLF 01366 5501 2104 2105 ; Temporary storage for DANDV... 2106 01367 GOOD: .BLOCK 1 ; the "good" value we wrote to memory 01371 6400 01372 6201 01373 0712 01374 6200 01375 1500 01376 6277 01377 5751 2107 01400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 45 BM Command -- Memory Block Move BTS6120.plx 2108 .TITLE BM Command -- Memory Block Move 2109 2110 2111 ; The BM command is used to move blocks of memory words from one location to 2112 ; another. It has three parameters - the source address range (two 15 bit 2113 ; numbers), and the destination address (a single 15 bit number). All words 2114 ; from the starting source address to the ending source address are transferred 2115 ; to the corresponding words starting at the destination address. More than 2116 ; one field may be transferred, and transfers may cross a field boundry. 2117 ; 2118 ; >BM 200-377 400 -> move all of page 1 in the current data field 2119 ; to page 2 of the same field. 2120 ; >BM 0-7777 10000 -> move all of field 0 to field 1 2121 ; >BM 00000-37777 40000 -> move fields 0 thru 3 to fields 4 thru 7 2122 ; 2123 ; Note that this command operates only on main memory - there is no 2124 ; corresponding block move command for panel memory! 2125 ; 2126 01400 6205 BMOVE: .PUSHJ @ZRANGE ; read the source address range 01401 5517 2127 01402 7420 SNL ; did he give 2 numbers ??? 2128 01403 5525 JMP @ZCOMERR ; no -- don't allow a one address range 2129 01404 6205 .PUSHJ @[RDADDR] ; now read the destination 01405 5777 2130 01406 6205 .PUSHJ @ZEOLTST ; this should be the end of the command 01407 5513 2131 01410 3037 DCA PNLMEM ; this command ALWAYS operates on main memory 2132 2133 ; Now copy words from the source to the destination... 2134 01411 6205 MOVE1: .PUSHJ @[SWPADR] ; swap the LOW/LOWFLD (the source address) 01412 5776 2135 01413 6205 .PUSHJ @ZRDMEM ; read a word from the source 01414 5522 2136 01415 6205 .PUSHJ @ZTSTADR ; go see if this is the last address 01416 5520 2137 01417 7630 SZL CLA ; is it the end ??? 2138 01420 7240 STA ; yes -- load -1 into the AC 2139 01421 3067 DCA COUNT ; and remember that fact for later 2140 01422 6205 .PUSHJ @ZNXTADR ; now increment the source address 01423 5521 2141 01424 6205 .PUSHJ @[SWPADR] ; swap the source back into LOW/LOWFLD 01425 5776 2142 01426 1044 TAD VALUE ; get the data we read from the source 2143 01427 6205 .PUSHJ @ZDANDV ; and deposit it in the destination 01430 5523 2144 01431 6205 .PUSHJ @ZNXTADR ; increment the destination address too 01432 5521 2145 01433 7430 SZL ; did we wrap out of field 7 ??? 2146 01434 5240 JMP MOVE2 ; yes -- stop here 2147 01435 2067 ISZ COUNT ; have we copied all the words ?? 2148 01436 5211 JMP MOVE1 ; no -- keep looping 2149 01437 6225 .POPJ ; yes -- that's all 2150 2151 ; Here if the destination address runs out of field 7... 2152 01440 4526 MOVE2: JMS @ZERROR ; don't allow that to continue 2153 01441 3464 ERRWRP ; ?WRAP AROUND PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 46 CK Command -- Checksum Memory BTS6120.plx 2154 .TITLE CK Command -- Checksum Memory 2155 2156 2157 ; This command will compute the checksum of all memory locations between the 2158 ; two addresses specified and the resulting 12 bit value is then printed 2159 ; on the terminal. This is useful for testing memory, comparing blocks of 2160 ; memory, and so on. Note that the checksum algorithm used rotates the 2161 ; accumulator one bit between each words, so blocks of memory with identical 2162 ; contents in different orders will give different results. 2163 ; 2164 ; >CK 10000-10177 -> checksum all of page 0, field 1 2165 ; 2166 ; Note that this command operates only on main memory - there is no 2167 ; corresponding command for panel memory! 2168 01442 6205 CKMEM: .PUSHJ @ZRANGE ; read a two address range 01443 5517 2169 01444 7420 SNL ; two addresses are required 2170 01445 5525 JMP @ZCOMERR ; ... 2171 01446 6205 .PUSHJ @ZEOLTST ; be sure this is the end of the command 01447 5513 2172 01450 3037 DCA PNLMEM ; this command ALWAYS operates on main memory 2173 01451 3046 DCA CHKSUM ; and clear the checksum accumulator 2174 2175 ; Read words and checksum them... 2176 01452 1046 CKMEM1: TAD CHKSUM ; get the previous total 2177 01453 7104 CLL RAL ; and shift it left one bit 2178 01454 7430 SZL ; did we shift out a one ?? 2179 01455 7001 IAC ; yes -- shift it in the right end 2180 01456 3046 DCA CHKSUM ; save that for a while 2181 01457 6205 .PUSHJ @ZRDMEM ; and go read a word from real memory 01460 5522 2182 01461 1046 TAD CHKSUM ; add it to the checksum 2183 01462 3046 DCA CHKSUM ; save the new checksum 2184 01463 6205 .PUSHJ @ZTSTADR ; compare the addresses next 01464 5520 2185 01465 7430 SZL ; are we all done ?? 2186 01466 5277 JMP TCKSUN ; yes -- type the checksum and return 2187 01467 6205 .PUSHJ @ZNXTADR ; no -- increment the address 01470 5521 2188 01471 5252 JMP CKMEM1 ; and proceed 2189 2190 ; This routine will type out the checksum currently contained in location 2191 ; CHKSUM. If the checksum isn't zero, it will type a question mark (making 2192 ; a pseudo error message) first... 2193 01472 1046 TCKSUM: TAD CHKSUM ; see if the checksum is zero 2194 01473 7650 SNA CLA ; ??? 2195 01474 5277 JMP TCKSUN ; yes -- type it normally 2196 01475 6205 .PUSHJ @[TQUEST] ; no -- type a question mark first 01476 5775 2197 2198 ; Now type the checksum... 2199 01477 4507 TCKSUN: JMS @ZINLMES ; type out the checksum message 2200 01500 3402 CKSMSG ; ... 2201 01501 1046 TAD CHKSUM ; get the actual checksum 2202 01502 5500 JMP @ZTOCT4C ; type it with a CRLF and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 47 CM and FM Commands -- Clear Memory and Fill Memory BTS6120.plx 2203 .TITLE CM and FM Commands -- Clear Memory and Fill Memory 2204 2205 2206 ; The FM command fills a range of memory locations with a constant. For 2207 ; example: 2208 ; 2209 ; >FM 7402 0-7777 -> fill all of field zero with HLT instructions 2210 ; >FM 7777 0-77777 -> fill all of memory with -1 2211 ; 2212 ; The second and third arguments (the address range) may be omitted, in 2213 ; which case all of memory is filled. 2214 ; 2215 ; Note that this command operates only on main memory - there is no 2216 ; corresponding command for panel memory! 2217 01503 6205 FLMEM: .PUSHJ @ZOCTNW ; read the constant to fill with 01504 5516 2218 01505 1065 TAD WORD ; get the desired value 2219 01506 5312 JMP CMEM0 ; then join the CM command 2220 2221 ; The CM command is identical to FM, except that the fill value is always 2222 ; zero (hence the name - "Clear" memory). For example: 2223 ; 2224 ; >CM 50000 57777 -> clear all of field 5 2225 ; >CM -> (with no arguments) clear all of memory! 2226 ; 2227 ; Like FM, this command operates only on main memory. There is no 2228 ; equivalent for panel memory. 2229 01507 6205 CMEM: .PUSHJ @ZGET ; advance the scanner to the break character 01510 5515 2230 01511 7200 CLA ; and throw it away for now 2231 01512 3044 CMEM0: DCA VALUE ; and fill with zeros 2232 01513 3035 DCA ADDR ; initialize the address range to start 2233 01514 3036 DCA ADRFLD ; at location 0000, field 0 2234 01515 7240 STA ; and to finish at location 7777, 2235 01516 3040 DCA HIGH ; ... 2236 01517 1131 TAD ZK70 ; field 7 2237 01520 3042 DCA HGHFLD ; ... 2238 01521 3037 DCA PNLMEM ; this command ALWAYS operates on main memory 2239 2240 ; See if there is an address range... 2241 01522 6205 .PUSHJ @ZSPACM0 ; get the break character 01523 5511 2242 01524 7650 SNA CLA ; is there any more out there ?? 2243 01525 5334 JMP CMEM1 ; no -- start filling 2244 01526 6205 .PUSHJ @ZBACKUP ; yes - backup to the first character 01527 5512 2245 01530 6205 .PUSHJ @ZRANGE ; and read the address range 01531 5517 2246 01532 6205 .PUSHJ @ZEOLTST ; then check for the end of the line 01533 5513 2247 2248 ; Clear/set memory locations... 2249 01534 1044 CMEM1: TAD VALUE ; get the value to store 2250 01535 6205 .PUSHJ @ZDANDV ; store it and verify 01536 5523 2251 01537 6205 .PUSHJ @ZTSTADR ; see if we have done all the addresses 01540 5520 2252 01541 7430 SZL ; well ?? 2253 01542 6225 .POPJ ; yes -- we can stop now 2254 01543 6205 .PUSHJ @ZNXTADR ; no -- increment the address field 01544 5521 2255 01545 5334 JMP CMEM1 ; then go clear this word PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 48 X / XP Command Stubs -- Disassemble memory BTS6120.plx 2256 .TITLE X / XP Command Stubs -- Disassemble memory 2257 2258 ; stubs in field 0 call actual functions in field 2 2259 01546 6223 DISASM: CXF 2 2260 01547 5774 JMP @[CMDX] 2261 2262 01550 6223 DISASMP: CXF 2 2263 01551 5773 JMP @[CMDXP] 2264 01573 0603 01574 0600 01575 7066 01576 6521 01577 6416 2265 01600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 49 WS Command -- Word Search Memory BTS6120.plx 2266 .TITLE WS Command -- Word Search Memory 2267 2268 2269 ; The WS command searches memory for a specific bit pattern. It accepts up 2270 ; to 4 operands: (1) the value to search for, (2) the starting search address, 2271 ; (3) the final search address, and (4) a search mask. All values except the 2272 ; first are optional and have appropriate defaults. Any location in the 2273 ; specified range which matches the given value after being masked is typed 2274 ; out along with its address. For example: 2275 ; 2276 ; >WS 6031 -> search all of memory for KSF instructions 2277 ; >WS 6031 30000-33777 -> search words 0..3377 of field 3 for KSFs 2278 ; >WS 6030 0-77777 7770 -> search memory for any keyboard IOTs 2279 ; 2280 ; N.B. this command operates only on main memory and there is no equivalent 2281 ; for panel memory. 2282 2283 ; Read the first (required) operand and set defaults for all the rest... 2284 01600 6205 SEARCH: .PUSHJ @ZOCTNW ; read the value to search for 01601 5516 2285 01602 1065 TAD WORD ; then get that 2286 01603 3272 DCA KEY ; and save it 2287 01604 3035 DCA ADDR ; set the starting address to 0 2288 01605 3036 DCA ADRFLD ; in field 0 2289 01606 7240 STA ; then stop at location 7777 2290 01607 3040 DCA HIGH ; ... 2291 01610 1131 TAD ZK70 ; field 7 2292 01611 3042 DCA HGHFLD ; ... 2293 01612 7240 STA ; and set the mask to 7777 2294 01613 3273 DCA MASK ; ... 2295 01614 3037 DCA PNLMEM ; this command _always_ searches main memory 2296 2297 ; Try to read any optional operands... 2298 01615 1050 TAD SAVCHR ; is there any more there ?? 2299 01616 7650 SNA CLA ; ??? 2300 01617 5233 JMP SEAR1 ; no -- start looking 2301 01620 6205 .PUSHJ @ZRANGE ; yes -- read the address range 01621 5517 2302 01622 1050 TAD SAVCHR ; is there a mask out there ?? 2303 01623 7650 SNA CLA ; ??? 2304 01624 5233 JMP SEAR1 ; no -- start looking 2305 01625 6205 .PUSHJ @ZOCTNW ; yes -- read the mask too 01626 5516 2306 01627 1065 TAD WORD ; load the mask 2307 01630 3273 DCA MASK ; and save that for later 2308 01631 6205 .PUSHJ @ZEOLTST ; this has to be the end of the line 01632 5513 2309 2310 ; Here to start the search... 2311 01633 3067 SEAR1: DCA COUNT ; count the number of matches we find 2312 01634 1272 TAD KEY ; get the search key 2313 01635 0273 AND MASK ; apply the mask to it too 2314 01636 7041 CIA ; make it negative 2315 01637 3272 DCA KEY ; and remember that instead 2316 2317 ; Look through memory for matches... 2318 01640 6205 SEAR2: .PUSHJ @[INCHRS] ; poll the operator for control-C 01641 5777 2319 01642 6205 .PUSHJ @ZRDMEM ; read a word from real memory 01643 5522 2320 01644 0273 AND MASK ; apply the mask to it 2321 01645 1272 TAD KEY ; and compare to the value 2322 01646 7640 SZA CLA ; does it match ?? 2323 01647 5256 JMP SEAR3 ; no -- skip it 2324 01650 6205 .PUSHJ @[TMEM] ; yes -- type the address and contents PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 50 WS Command -- Word Search Memory BTS6120.plx 01651 5776 2325 01652 6205 .PUSHJ @ZCRLF ; then finish the line 01653 5506 2326 01654 7240 STA ; make the AC non-zero 2327 01655 3067 DCA COUNT ; and remember that we found a match 2328 01656 6205 SEAR3: .PUSHJ @ZTSTADR ; see if we have looked everywhere 01657 5520 2329 01660 7430 SZL ; well ?? 2330 01661 5265 JMP SEAR4 ; yes -- finish up now 2331 01662 6205 .PUSHJ @ZNXTADR ; no -- increment the address 01663 5521 2332 01664 5240 JMP SEAR2 ; and keep looking 2333 2334 ; Here at the end of the search... 2335 01665 1067 SEAR4: TAD COUNT ; see how many matches there were 2336 01666 7640 SZA CLA ; were there any at all ?? 2337 01667 6225 .POPJ ; yes -- that's fine 2338 01670 4526 JMS @ZERROR ; no -- give an error message 2339 01671 3442 ERRSRF ; ? SEARCH FAILS 2340 2341 ; Temporary storage for the SEARCH routine... 2342 01672 KEY: .BLOCK 1 ; a search key 2343 01673 MASK: .BLOCK 1 ; a search mask 2344 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 51 BL Command -- List Breakpoints BTS6120.plx 2345 .TITLE BL Command -- List Breakpoints 2346 2347 2348 ; This command will list all the breakpoints which are currently set in 2349 ; the user's program. It has no operands... 2350 ; 2351 ; >BL 2352 ; 2353 01674 6205 BLIST: .PUSHJ @ZEOLNXT ; there should be no more 01675 5514 2354 01676 6205 .PUSHJ BSETUP ; set up X1, X2 and COUNT 01677 5324 2355 01700 3044 DCA VALUE ; count the number of breakpoints here 2356 2357 ; Loop through the breakpoint table and list all valid breakpoints... 2358 01701 1410 BLIST1: TAD @X1 ; get the address of this breakpoint 2359 01702 3035 DCA ADDR ; and remember that 2360 01703 1411 TAD @X2 ; then get the corresponding field 2361 01704 3036 DCA ADRFLD ; ... 2362 01705 1035 TAD ADDR ; let's see that address again 2363 01706 7650 SNA CLA ; is there really a breakpoint set here ?? 2364 01707 5315 JMP BLIST2 ; no -- on to the next one 2365 01710 6205 .PUSHJ @[TMEM] ; yes -- type out the address and memory 01711 5776 2366 01712 6205 .PUSHJ @ZCRLF ; finish this line 01713 5506 2367 01714 2044 ISZ VALUE ; and count the number we find 2368 01715 2067 BLIST2: ISZ COUNT ; are there more breakpoints to do? 2369 01716 5301 JMP BLIST1 ; yes - keep going 2370 2371 ; Here after going through the table... 2372 01717 1044 TAD VALUE ; see how many we found 2373 01720 7640 SZA CLA ; any at all ?? 2374 01721 6225 .POPJ ; yes -- that's great 2375 01722 4526 JMS @ZERROR ; no -- print an error message 2376 01723 3653 ERRNBP ; ?NONE SET 2377 2378 ; This routine will set up the pointers for traversing the break point 2379 ; table. X1 always points to the break point address table, X2 points to 2380 ; the break point field table, and X3 points to the break point data table. 2381 ; COUNT is initialized to the negative of the table size (all three tables 2382 ; are the same size) so that it can be used as an ISZ counter. This same 2383 ; arrangement of pointers is used by all the routines that operate on 2384 ; breakpoints. 2385 01724 7200 BSETUP: CLA ; just in case... 2386 01725 1375 TAD [BPTADR-1] ; X1 points to the address table 2387 01726 3010 DCA X1 ; ... 2388 01727 1374 TAD [BPTFLD-1] ; X2 points to the field table 2389 01730 3011 DCA X2 ; ... 2390 01731 1373 TAD [BPTDAT-1] ; X3 points to the data table 2391 01732 3012 DCA X3 ; ... 2392 01733 1372 TAD [-MAXBPT] ; and COUNT is the table size 2393 01734 3067 DCA COUNT ; ... 2394 01735 3037 DCA PNLMEM ; break points always refer to main memory! 2395 01736 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 52 Search for Breakpoints BTS6120.plx 2396 .TITLE Search for Breakpoints 2397 2398 2399 ; This routine will search the breakpoint table to see if there is a one set 2400 ; at the location specified by ADDR and ADRFLD. If one is found, it will 2401 ; return with the LINK set and with X1/X2 pointing to the table entry. If 2402 ; there is no breakpoint at the specified address, it returns with the LINK 2403 ; cleared. 2404 01737 6205 BPTFND: .PUSHJ BSETUP ; set up X1, X2 and COUNT 01740 5324 2405 2406 ; Look through the entire table... 2407 01741 1410 BPTFN1: TAD @X1 ; get this breakpoint address 2408 01742 7450 SNA ; is there breakpoint here at all ?? 2409 01743 5357 JMP BPTFN2 ; no -- just forget it 2410 01744 7041 CIA ; make this address negative 2411 01745 1035 TAD ADDR ; and compare to what we want 2412 01746 7640 SZA CLA ; does it match ?? 2413 01747 5357 JMP BPTFN2 ; no -- on to the next one 2414 01750 1411 TAD @X2 ; yes -- get the field number 2415 01751 7041 CIA ; make that negative 2416 01752 1036 TAD ADRFLD ; and compare to the field we need 2417 01753 7640 SZA CLA ; do they match to ?? 2418 01754 5360 JMP BPTFN3 ; no -- keep looking 2419 01755 7120 STL ; yes -- set the LINK 2420 01756 6225 .POPJ ; and stop right now 2421 2422 ; Here if the current address dosen't match... 2423 01757 2011 BPTFN2: ISZ X2 ; increment the field pointer too 2424 01760 2067 BPTFN3: ISZ COUNT ; have we searched the entire table? 2425 01761 5341 JMP BPTFN1 ; no -- keep looking 2426 01762 7100 CLL ; yes -- clear the LINK 2427 01763 6225 .POPJ ; and return 2428 01772 7770 01773 0220 01774 0210 01775 0200 01776 1060 01777 7477 2429 02000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 53 BR Command -- Remove Breakpoints BTS6120.plx 2430 .TITLE BR Command -- Remove Breakpoints 2431 2432 2433 ; The BR command removes a breakpoint at a specific address or, if no 2434 ; operand is given, removes all breakpoints. For example: 2435 ; 2436 ; >BR 17605 -> remove the breakpoint at location 7605, field 1 2437 ; >BR -> remove all breakpoints regardless of address 2438 ; 2439 02000 6205 BREMOV: .PUSHJ @ZGET ; get the next character 02001 5515 2440 02002 7650 SNA CLA ; is it the end of the line ?? 2441 02003 5226 JMP BPTCLR ; yes -- clear all breakpoints 2442 02004 6205 .PUSHJ @ZBACKUP ; no -- backup the scanner 02005 5512 2443 02006 6205 .PUSHJ @[OCTNI] ; then read an address 02007 5777 2444 02010 1065 TAD WORD ; get the breakpoint address 2445 02011 7450 SNA ; be sure it isn't location zero 2446 02012 5525 JMP @ZCOMERR ; that isn't legal 2447 02013 3035 DCA ADDR ; save the address of the breakpoint 2448 2449 ; Here to remove a single breakpoint... 2450 02014 6205 .PUSHJ @[BPTFND] ; look for this breakpoint it the table 02015 5776 2451 02016 7420 SNL ; did we find it ?? 2452 02017 5224 JMP BREMO1 ; no -- there's no breakpoint at that address 2453 02020 1010 TAD X1 ; yes -- get the pointer to BPTADR 2454 02021 3035 DCA ADDR ; and save it in a non-autoindex location 2455 02022 3435 DCA @ADDR ; clear the BPTADR entry (to remove it) 2456 02023 6225 .POPJ ; and that's all 2457 2458 ; Here if the breakpoint does not exist... 2459 02024 4526 BREMO1: JMS @ZERROR ; give an appropriate error message 2460 02025 3662 ERRNST ; ?NOT SET 2461 2462 ; Here to clear all breakpoints... 2463 02026 6205 BPTCLR: .PUSHJ @[BSETUP] ; setup X1, X2, X3 and COUNT 02027 5775 2464 02030 3410 BPTCL2: DCA @X1 ; clear this breakpoint 2465 02031 3411 DCA @X2 ; ... 2466 02032 3412 DCA @X3 ; ... 2467 02033 2067 ISZ COUNT ; have we done them all? 2468 02034 5230 JMP BPTCL2 ; no -- keep looping 2469 02035 6225 .POPJ ; yes -- that's it PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 54 BP Command -- Set Breakpoints BTS6120.plx 2470 .TITLE BP Command -- Set Breakpoints 2471 2472 2473 ; The BP command sets a breakpoint in the main memory (aka user) program. 2474 ; It requires a single argument giving the 15 bit address where the breakpoint 2475 ; is to be set. For example: 2476 ; 2477 ; >BP 07605 -> set a breakpoint at location 7605, field 0 2478 ; >BP 7605 -> same, but in the current instruction field 2479 ; 2480 ; It's not possible to set a breakpoint at location zero in any field because 2481 ; the monitor uses zero as a marker for an unused breakpoint table entry. 2482 ; 2483 ; Note that this routine only enters the breakpoint into the table - nothing 2484 ; actually happens to the main memory program until we start running it and 2485 ; the BPTINS routine is called. 2486 02036 6205 BPTCOM: .PUSHJ @[OCTNI] ; go read the address 02037 5777 2487 02040 1065 TAD WORD ; get the address operand 2488 02041 7450 SNA ; be sure it isn't zero 2489 02042 5525 JMP @ZCOMERR ; no breakpoints at address zero 2490 02043 3035 DCA ADDR ; and put it in a safe place 2491 02044 6205 .PUSHJ @ZEOLTST ; then test for the end of the line 02045 5513 2492 2493 ; See if this breakpoint is already in the table.. 2494 02046 6205 .PUSHJ @[BPTFND] ; ... 02047 5776 2495 02050 7620 SNL CLA ; was it found ?? 2496 02051 5254 JMP BPTCO1 ; no -- go try to add it 2497 02052 4526 JMS @ZERROR ; yes -- say that it is already set 2498 02053 3670 ERRAST ; ?ALREADY SET 2499 2500 ; Here to search for a free location in the table... 2501 02054 6205 BPTCO1: .PUSHJ @[BSETUP] ; setup X1 and COUNT 02055 5775 2502 02056 2011 BPTCO2: ISZ X2 ; keep X1 and X2 in sync 2503 02057 1410 TAD @X1 ; get this table entry 2504 02060 7650 SNA CLA ; have we found an empty one ?? 2505 02061 5266 JMP BPTCO3 ; yes -- great 2506 02062 2067 ISZ COUNT ; have we searched the entire table? 2507 02063 5256 JMP BPTCO2 ; no -- keep trying 2508 02064 4526 JMS @ZERROR ; yes -- say that the table is full 2509 02065 3701 ERRBTF ; ?TABLE FULL 2510 2511 ; Here to insert the breakpoint in the table... 2512 02066 1010 BPTCO3: TAD X1 ; get the pointer to the free location 2513 02067 3041 DCA LOW ; and put it in a non-autoindex location 2514 02070 1035 TAD ADDR ; get the desired address 2515 02071 3441 DCA @LOW ; and store that in the table 2516 02072 1011 TAD X2 ; do the same with the field table 2517 02073 3041 DCA LOW ; ... 2518 02074 1036 TAD ADRFLD ; get the field we need 2519 02075 3441 DCA @LOW ; and put that in the table 2520 02076 6225 .POPJ ; then that's all PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 55 Insert Breakpoints in Memory BTS6120.plx 2521 .TITLE Insert Breakpoints in Memory 2522 2523 2524 ; This routine will insert breakpoints in main memory (aka the user program) 2525 ; at the locations specified in the breakpoint table. The current contents of 2526 ; each breakpoint location are stored in CP memory in the BPTDAT table, and 2527 ; then are replaced by a BPT instruction. This routine is normally called 2528 ; just before returning control to the user's program. 2529 02077 6205 BPTINS: .PUSHJ @[BSETUP] ; set up X1, X2, X3 and COUNT 02100 5775 2530 2531 ; Loop through the table and insert the breakpoints... 2532 02101 1410 BPTIN1: TAD @X1 ; get the next address 2533 02102 7450 SNA ; is there a breakpoint set there ?? 2534 02103 5316 JMP BPTIN2 ; no -- proceed to the next one 2535 02104 3035 DCA ADDR ; yes -- save the address 2536 02105 1411 TAD @X2 ; and get the field 2537 02106 3036 DCA ADRFLD ; save that too 2538 02107 6205 .PUSHJ @ZRDMEM ; go read the contents of that location 02110 5522 2539 02111 3412 DCA @X3 ; save the user's data in the table 2540 02112 1374 TAD [BPT] ; then get a breakpoint instruction 2541 02113 6205 .PUSHJ @ZDANDV ; deposit that in the breakpoint location 02114 5523 2542 02115 5320 JMP BPTIN3 ; proceed to the next one 2543 2544 ; See if we have finished the table... 2545 02116 2011 BPTIN2: ISZ X2 ; keep the pointers in sync 2546 02117 2012 ISZ X3 ; ... 2547 02120 2067 BPTIN3: ISZ COUNT ; have we been all the way through ?? 2548 02121 5301 JMP BPTIN1 ; no -- keep going 2549 02122 6225 .POPJ ; yes -- quit now PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 56 Remove Breakpoints from Memory BTS6120.plx 2550 .TITLE Remove Breakpoints from Memory 2551 2552 2553 ; This routine will restore the original contents of all breakpoint locations 2554 ; in the main memory program from the table at BPTDAT. It is normally called 2555 ; after a trap to CP memory occurs. Breakpoints must be restored so that the 2556 ; user may examine or change them. 2557 02123 6205 BPTRMV: .PUSHJ @[BSETUP] ; set up X1, X2, X3 and COUNT 02124 5775 2558 2559 ; Loop through the breakpoint table and restore all data... 2560 02125 1410 BPTRM1: TAD @X1 ; get the address of this breakpoint 2561 02126 7450 SNA ; is there one there at all ?? 2562 02127 5337 JMP BPTRM2 ; no -- on to the next one 2563 02130 3035 DCA ADDR ; yes -- remember the address 2564 02131 1411 TAD @X2 ; then get the correct field too 2565 02132 3036 DCA ADRFLD ; ... 2566 02133 1412 TAD @X3 ; finally get the original contents 2567 02134 6205 .PUSHJ @ZDANDV ; deposit and verify it back where it goes 02135 5523 2568 02136 5341 JMP BPTRM3 ; on to the next one 2569 2570 ; Here to advance to the next breakpoint... 2571 02137 2011 BPTRM2: ISZ X2 ; keep the pointers in sync 2572 02140 2012 ISZ X3 ; ... 2573 02141 2067 BPTRM3: ISZ COUNT ; have we done them all ?? 2574 02142 5325 JMP BPTRM1 ; no -- keep looping 2575 02143 6225 .POPJ ; yes -- that's it for this time PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 57 TR Command -- Single Instruction with Trace BTS6120.plx 2576 .TITLE TR Command -- Single Instruction with Trace 2577 2578 2579 ; The TR command will execute one instruction of the user's program and then 2580 ; print the registers. It always executes one instruction, but it may be 2581 ; combined with the repeat (RP) command to execute multiple instructions. 2582 02144 6205 SICOM: .PUSHJ @ZEOLNXT ; there are no operands 02145 5514 2583 2584 ; Figure out what we are going to execute... 2585 02146 1002 TRACE: TAD UFLAGS ; get the instruction field 2586 02147 0131 AND ZK70 ; ... 2587 02150 3036 DCA ADRFLD ; so we can change to that field 2588 02151 1000 TAD UPC ; get the current main memory PC 2589 02152 3035 DCA ADDR ; and point to that 2590 02153 1000 TAD UPC ; also save a copy for the disassember 2591 02154 3006 DCA UIRPC ; to print 2592 02155 3037 DCA PNLMEM ; always access main memory 2593 02156 6205 .PUSHJ @ZRDMEM ; go read what we're about to execute 02157 5522 2594 02160 3007 DCA UIR ; remember that for later 2595 2596 ; Execute 1 instruction... 2597 02161 6205 .PUSHJ @[SINGLE] ; just like it says 02162 5773 2598 2599 ; Print all the registers... 2600 02163 6205 .PUSHJ @[TYPEIR] ; first type the UIR 02164 5772 2601 02165 5771 JMP @[REGLSC] ; and then print the rest and return 2602 02171 1240 02172 1263 02173 2202 02174 6236 02175 1724 02176 1737 02177 7000 2603 02200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 58 SI and P Commands - Single Instruction and Proceed BTS6120.plx 2604 .TITLE SI and P Commands - Single Instruction and Proceed 2605 2606 2607 ; This routine will execute a single instruction of the user's program and 2608 ; then return to the caller. It is used directly to execute the SI command, 2609 ; and indirectly by many other commands... 2610 2611 ; Here for the SI command... 2612 02200 6205 SNCOM: .PUSHJ @ZEOLNXT ; make sure that there is no more 02201 5514 2613 2614 ; Setting the HALT flip flop will cause the HM6120 to immediately trap back 2615 ; to panel mode after it has executed exactly one instruction of the main 2616 ; memory program. This makes it easy to implement a single step function. 2617 ; 2618 ; Note that SINGLE is a subroutine which you can actually call, via a 2619 ; .PUSHJ, from anywhere in the monitor and it will return after the main 2620 ; memory instruction has been executed. This little bit of magic happens 2621 ; because the code at CONT1 saves the monitor stack and then restores 2622 ; it after the single instruction trap. 2623 02202 6003 SINGLE: PGO ; first make sure the HALT flip flop is cleared 2624 02203 7402 HLT ; then make sure it's set 2625 02204 7240 STA ; set the software single step flag 2626 02205 3047 DCA SIMFLG ; ... so that CPSAVE will know what to do 2627 02206 5227 JMP CONT1 ; then restore the registers and go 2628 2629 ; The P command is used to proceed after the main memory program has stopped 2630 ; at a breakpoint. You can't simply continue at this point because the PC 2631 ; points to the location of the breakpoint, and Continue would simply break 2632 ; again, instantly. The Proceed command gets around this problem by first 2633 ; executing a single instruction, and then contining normally. 2634 02207 6205 PROCEE: .PUSHJ @ZEOLNXT ; this command has no operands 02210 5514 2635 02211 6205 .PUSHJ SINGLE ; first execute the location under the BPT 02212 5202 2636 02213 5216 JMP CONT ; then restore the breakpoints and continue PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 59 C Command - Restore Main Memory Context and Continue BTS6120.plx 2637 .TITLE C Command - Restore Main Memory Context and Continue 2638 2639 2640 ; This routine will restore all the user's registers and return to his 2641 ; program. It is called directly for the continue command, and is used 2642 ; indirectly (to change contexts) by several other commands. 2643 ; 2644 ; When this routine finishes in the most literal sense, the user mode 2645 ; program is running and the monitor is no longer active. However the 2646 ; CONT function can and will actually return, via a POPJ, if the user 2647 ; program causes a breakpoint or single instruction trap. This property is 2648 ; critical to the operation of the Proceed, TRace and Single Instruction 2649 ; commands! 2650 2651 ; Here for the continue command... 2652 02214 6205 CONTCM: .PUSHJ @ZEOLNXT ; continue has no operands 02215 5514 2653 2654 ; If we have a front panel and the HALT switch is currently DOWN, then 2655 ; we want to execute a single instruction only. Only if the HALT switch 2656 ; is UP (or if there's no front panel at all), do we run free! 2657 02216 4777 CONT: JMS @[CHKHLT] ; test the HALT switch 2658 02217 5776 JMP @[TRACE] ; down - trace one instruction instead 2659 ; up - proceed normally 2660 2661 ; Select free running mode and insert all breakpoints... 2662 02220 6205 .PUSHJ @[BPTINS] ; insert all breakpoints 02221 5775 2663 02222 3047 DCA SIMFLG ; clear our software single step flag 2664 02223 6003 PGO ; make sure the HALT flip-flop is cleared 2665 02224 5227 JMP CONT1 ; restore registers and resume 2666 2667 2668 ; The monitor call processor, MCALL, jumps here after it finishes executing 2669 ; a PR0 ROM call. Some of these calls, especially ones that access the disk, 2670 ; take a fairly long time and if the user flips the HALT switch while the 2671 ; program is doing a lot of disk I/O there's a good chance we'll miss it. 2672 ; To fix that, we check the state of the HALT switch after completing a 2673 ; ROM call and just halt if it's been flipped while were busy. 2674 02225 4777 CONT2: JMS @[CHKHLT] ; test the HALT switch 2675 02226 5774 JMP @[HALTED] ; down - pretend we halted after the MUUO 2676 ; otherwise fall into CONT1 and return 2677 2678 2679 ; Restore all registers and context switch. Naturally, part of this involves 2680 ; restoring the original user mode stack pointers, so before we lose our own 2681 ; stack forever, we save a copy of the last monitor stack pointer in RAM. It 2682 ; gets restored by the code at CPSAVE after a breakpoint or single instruction 2683 ; trap. 2684 ; 2685 ; Another gotcha - if a transition on CPREQ L occurs while we're in panel 2686 ; mode, the BTSTRP flag in the panel status will still set anyway. If that 2687 ; happens and we try to continue, the 6120 will trap back to panel mode 2688 ; immediately. The simplest fix for this is to do a dummy read of the panel 2689 ; status flags, which clears them. 2690 02227 6207 CONT1: RSP1 ; get our monitor's stack pointer 2691 02230 3142 DCA STKSAV ; and save it for later 2692 02231 6437 RLON ; turn the RUN LED on 2693 02232 6440 POST+0 ; and show post code 0 2694 02233 6430 CCPR ; make sure no panel request is pending 2695 02234 6000 PRS ; dummy read of panel status to clear BTSTRP 2696 02235 7200 CLA ; ... 2697 02236 1004 TAD USP1 ; reload stack pointer #1 2698 02237 6217 LSP1 ; ... 2699 02240 1005 TAD USP2 ; and stack #2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 60 C Command - Restore Main Memory Context and Continue BTS6120.plx 2700 02241 6237 LSP2 ; ... 2701 02242 1003 TAD UMQ ; restore the MQ register 2702 02243 7421 MQL ; ... 2703 02244 1002 TAD UFLAGS ; restore the flags, including IF, DF and LINK 2704 02245 6005 RTF ; ... 2705 02246 1001 TAD UAC ; restore the AC 2706 02247 6004 PEX ; exit panel mode 2707 02250 5400 JMP @UPC ; and, lastly, restore the PC 2708 2709 ; At this point we're running the main memory program. If that program 2710 ; causes a breakpoint or single instruction trap, then the HM6120 will enter 2711 ; the CPSAVE routine thru the vector at 7777. After it figures out the reason 2712 ; for the trap, CPSAVE will restore the original monitor's stack, from STKSAV, 2713 ; and execute a .POPJ. Only then will this routine "return". PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 61 ST Command -- Start a Main Memory Program BTS6120.plx 2714 .TITLE ST Command -- Start a Main Memory Program 2715 2716 2717 ; The start command initializes the CPU registers and all I/O devices and 2718 ; then transfers control to a main memory (user) program. A single, optional, 2719 ; argument may be given to specify the start address of the the main memory 2720 ; program. If the start address is omitted, then the default is location 2721 ; 7777 of field 0 (this is a little strange by PDP-8 standards, but it's the 2722 ; typical reset vector for 6100 and 6120 devices). For example: 2723 ; 2724 ; >ST 00200 - start at location 200 in field 0 (DF is also 0) 2725 ; >ST 70200 - start at location 200 in field 7 (DF is also 7) 2726 ; >ST - start at location 7777 of field 0 (DF is also 0) 2727 ; 2728 02251 6205 START: .PUSHJ @ZGET ; get the next character 02252 5515 2729 02253 7650 SNA CLA ; is there anything out there ?? 2730 02254 5275 JMP START1 ; no -- use the defaults 2731 2732 ; Start at a specific (non-default) address... 2733 02255 6205 .PUSHJ @ZBACKUP ; backup to the start of the address 02256 5512 2734 02257 6205 .PUSHJ @[OCTNI] ; then read it 02260 5773 2735 02261 6205 .PUSHJ @ZEOLTST ; now it has to be the end of the line 02262 5513 2736 02263 6205 .PUSHJ CLRCPU ; clear the saved main memory registers 02264 5312 2737 02265 1065 TAD WORD ; and overwrite the PC with the desired address 2738 02266 3000 DCA UPC ; ... 2739 02267 1036 TAD ADRFLD ; get the start field 2740 02270 7112 CLL RTR ; and make the DF be the same 2741 02271 7106 CLL RTL ; ... 2742 02272 1036 TAD ADRFLD ; ... 2743 02273 3002 DCA UFLAGS ; those are the default processor flags 2744 02274 5216 JMP CONT ; insert any breakpoints and then go 2745 2746 ; Start at the default address. 2747 02275 6205 START1: .PUSHJ CLRCPU ; set all main saved CPU registers to default 02276 5312 2748 02277 5216 JMP CONT ; and then start there PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 62 MR Command - Master Reset BTS6120.plx 2749 .TITLE MR Command - Master Reset 2750 2751 2752 ; The MR command executes a CAF instruction to assert IOCLR L and initialize 2753 ; all external I/O devices, and then it resets the saved state of the main 2754 ; memory program to the "default" values. From the point of view of an I/O 2755 ; device on the bus, this is equivalent to pressing the RESET button, but it 2756 ; doesn't actually reset the CPU itself (which would re-initialize this 2757 ; monitor!). This command doesn't have any effect on the contents of main 2758 ; memory. 2759 02300 6205 CLRCOM: .PUSHJ @ZEOLNXT ; There are no operands 02301 5514 2760 2761 ; Initialize the saved user context... 2762 02302 6205 .PUSHJ CLRCPU ; clear UAC, UPC, UMQ, etc... 02303 5312 2763 2764 ; Execute a CAF instruction to clear all I/O devices. On the IM6100 we 2765 ; couldn't do this, since CAF would also clear the CP flag (!), but the 6120 2766 ; designers allowed for this case. 2767 ; 2768 ; Unfortunately IOCLR L also resets the console UART, which plays havoc 2769 ; with any character that we might be transmitting at the moment. The only 2770 ; safe thing is to wait for the console to finish before executing the CAF. 2771 ; Note that this will _leave_ the console flag cleared, which is the way a 2772 ; real PDP-8 program should expect it (clearing a real PDP-8 clears the 2773 ; console flag too, after all). 2774 02304 6041 TSF ; has the console finished yet? 2775 02305 5304 JMP .-1 ; no - wait for it 2776 02306 6007 CAF ; clear all I/O flags 2777 2778 ; Reset the IDE disk too. If none is attached, then this is harmless... 2779 ;[250] JMS @ZPUSHJ1 ; (cross field call) 2780 ;[250] IDEINI ; reset the IDE disk and then return 2781 02307 4527 JMS @ZPUSHJ1 ; (cross field call) 2782 02310 1713 INIPMP ; and initialize the partition map 2783 02311 5772 JMP @[EXMEM] ; sync the FP6120 display and we're done 2784 2785 2786 ; This routine is called by the START and RESET commands and at system 2787 ; initialization to clear the saved user context... 2788 02312 7200 CLRCPU: CLA ; start with all zeros 2789 02313 3001 DCA UAC ; clear the AC 2790 02314 3003 DCA UMQ ; and the MQ 2791 02315 3002 DCA UFLAGS ; the DF, IF and LINK 2792 02316 3004 DCA USP1 ; stack pointer #1 2793 02317 3005 DCA USP2 ; and #2 2794 02320 3061 DCA FPPGMM ; clear the front panel program mode 2795 02321 7240 STA ; then finally set the PC to 7777 2796 02322 3000 DCA UPC ; ... 2797 02323 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 63 EX Command - Execute IOT Instructions BTS6120.plx 2798 .TITLE EX Command - Execute IOT Instructions 2799 2800 2801 ; The EX command allows a user to type in and execute an IOT instruction 2802 ; directly from the terminal, which can be very useful for testing peripheral 2803 ; devices. Either one or two operands are allowed - the first is the octal 2804 ; code of the IOT to be executed, and the second (which is optional) is a 2805 ; value to be placed in the AC before the IOT is executed. If it is omitted, 2806 ; zero is placed in the AC. After the instruction is executed, the word SKIP 2807 ; is typed if the instruction skipped, along with the new contents of the AC. 2808 ; 2809 ; >EX 6471 -> execute IOT 6741 (the AC will be cleared) 2810 ; >EX 6474 1176 -> put 1176 in the AC and execute IOT 6474 2811 ; 2812 ; WARNING - some care must be exercised with this command, since executing 2813 ; the wrong IOT can crash the monitor! 2814 02324 6205 XCTCOM: .PUSHJ @ZOCTNW ; go read the IOT instruction code 02325 5516 2815 02326 1065 TAD WORD ; then get the value 2816 02327 3350 DCA XCTBLK ; save that where we'll execute it 2817 02330 3065 DCA WORD ; assume to use zero in the AC 2818 02331 1050 TAD SAVCHR ; next get the break character 2819 02332 7650 SNA CLA ; was it the end of the line ?? 2820 02333 5340 JMP XCT1 ; yes -- default to zero 2821 02334 6205 .PUSHJ @ZOCTNW ; no -- read another number 02335 5516 2822 02336 6205 .PUSHJ @ZEOLTST ; then test for the end of the line 02337 5513 2823 2824 ; Be sure the instruction is really an IOT... 2825 02340 1350 XCT1: TAD XCTBLK ; get the instruction 2826 02341 1371 TAD [-6000] ; compare it to 6000 2827 02342 7700 SMA CLA ; is it an IOT or OPR instruction ? 2828 02343 5346 JMP XCT2 ; yes -- that's OK 2829 02344 4526 JMS @ZERROR ; no -- don't allow this 2830 02345 3430 ERRILV ; ?ILLEGAL VALUE 2831 2832 ; Execute the instruction... 2833 02346 3067 XCT2: DCA COUNT ; will be non-zero if the IOT doesn't skip 2834 02347 1065 TAD WORD ; get the value we're supposed to put in the AC 2835 02350 7000 XCTBLK: NOP ; gets overwritten with the IOT to execute 2836 02351 2067 ISZ COUNT ; set the flag if it doesn't skip 2837 02352 3044 DCA VALUE ; and remember what is left in the AC 2838 2839 ; Print the results of the instruction.. 2840 02353 1067 TAD COUNT ; see if it skipped 2841 02354 7640 SZA CLA ; well ?? 2842 02355 5360 JMP XCT3 ; no -- no message 2843 02356 4507 JMS @ZINLMES ; yes -- say that it did 2844 02357 3475 SKPMSG ; ... 2845 02360 4507 XCT3: JMS @ZINLMES ; then print the AC after the instruction 2846 02361 3711 ACNAME ; ... 2847 02362 1044 TAD VALUE ; ... 2848 02363 5500 JMP @ZTOCT4C ; in octal, with a CRLF, and return 2849 02371 2000 02372 5751 02373 7000 02374 7711 02375 2077 02376 2146 02377 6031 2850 02400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 64 OS/8 Bootstrap BTS6120.plx 2851 .TITLE OS/8 Bootstrap 2852 2853 2854 ; How to boot OS/8 (there's lots of documentation on how to write a device 2855 ; handler, even a system handler, but I couldn't find a description of how 2856 ; to make a bootable device anywhere!): 2857 ; 2858 ; The primary bootstrap for a device (the one which you have to toggle in 2859 ; with the switches!) normally loads cylinder 0, head 0, sector 0 (which is 2860 ; the equivalent to OS/8 logical block zero) into memory page zero field zero. 2861 ; The code loaded into page zero is then started in some device specific way, 2862 ; but usually the primary bootstrap is overwritten by this data and the CPU 2863 ; just "ends up" there. 2864 ; 2865 ; The first few words of block zero are called the secondary bootstrap, and 2866 ; it's normally found in the header for the system device handler. OS/8 BUILD 2867 ; copies this code from the handler to block zero when it builds the system 2868 ; device. The second half of block zero contains the system handler, what's 2869 ; resident in page 7600 while OS/8 is running, plus some OS/8 resident code 2870 ; that BUILD wraps around it. All of the second half of block zero must be 2871 ; loaded into page 7600, field 0 by the secondary bootstrap. 2872 ; 2873 ; The remainder of the first half of block zero, the part after the secondary 2874 ; bootstrap, contains the OS/8 resident code for field 1. This starts some 2875 ; where around offset 47 in the first half of block zero, and this code needs 2876 ; to be loaded into the corresponding locations of page 7600, field 1. The 2877 ; remaining words in page 7600, field 1 (i.e. those that belong to the 2878 ; secondary bootstrap) OS/8 uses for tables and their initial values are 2879 ; unimportant. It suffices to simply copy all of the first half of block zero 2880 ; to page 7600, field 1. 2881 ; 2882 ; All this discussion presupposes a single page system handler, as we have 2883 ; here. For a two page handler BUILD will put the second page in the first 2884 ; half of block 66 on the system device and I believe (although I can't 2885 ; guarantee it) that the second half of this block also contains an image 2886 ; of the OS/8 resident code at page 7600, field 1. This would make it the 2887 ; same as, excepting the bootstrap part, the first half of block zero. In 2888 ; the case of a two page handler, the secondary bootstrap is also responsible 2889 ; for loading the second handler page from block 66 into page 7600, field 2. 2890 ; OS/8 bootstrap code (secondary bootstrap). 2891 ; 2892 ; Once everything has been loaded, the secondary bootstrap can simply do a 2893 ; "CDF CIF 0" and then jump to location 7600 to load the keyboard monitor. 2894 ; 2895 ; The primary bootstrap for the SBC6120 RAM and IDE disks are six words 2896 ; loaded in locations 0 thru 5: 2897 ; 2898 ; 0000/ 6206 PR0 / execute a panel request 2899 ; 0001/ 0001 1 / 1 for RAM disk, 4 for IDE disk 2900 ; 0002/ 0100 0100 / read one page into field zero 2901 ; 0003/ 0000 0000 / location zero 2902 ; 0004/ 0000 0000 / from page/block zero of the device 2903 ; 0005/ 7402 HLT / should never get here 2904 ; 2905 ; If all goes well, the HLT in location 5 is never executed - it gets 2906 ; overwritten by the secondary bootstrap code before the ROM returns from 2907 ; the PR0 function. 2908 ; 2909 ; The B (BOOT) command in BTS6120 actually bypasses the primary bootstrap 2910 ; step and simply reads block zero of the boot device into page zero, field 2911 ; zero directly. The VM01 and ID01 secondary bootstraps all contain a special 2912 ; "key" in words 0 thru 4, the ones which would normally overwrite the primary 2913 ; boostrap, and BTS6120 looks for this key to identify a bootable volume. 2914 ; If the key is found, then BTS6120 simply jumps to main memory location 5 2915 ; to start the secondary bootstrap and finish loading OS/8. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 65 OS/8 Bootstrap BTS6120.plx 2916 ; 2917 ; This system should also work for any other, non OS/8, system provided that 2918 ; it uses the same primary bootstrap shown above and that its secondary boot 2919 ; contains the special key in the first five words. As long as the secondary 2920 ; bootstrap starts at offset 5, the remainder of its code is unimportant to 2921 ; BTS6120 and it can do anything it likes. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 66 Boot Sniffer BTS6120.plx 2922 .TITLE Boot Sniffer 2923 2924 2925 ; The secondary bootstraps for both VM01 and ID01 devices contain a special 2926 ; key, the ASCIZ string "BOOT", in the first five words. The caller is 2927 ; expected to read block zero of the boot device into memory, and then call 2928 ; this routine to examine page zero, field zero, of main memory to determine 2929 ; if a valid secondary bootstrap exists. If the key is found, then the LINK 2930 ; will be cleared on return... 2931 02400 1377 CKBOOT: TAD [BOOKEY-1] ; point X1 to the key string 2932 02401 3010 DCA X1 ; ... 2933 02402 7240 NL7777 ; and point X2 to page zero of main memory 2934 02403 3011 DCA X2 ; ... 2935 02404 7100 CKBOO1: CLL ; be sure the LINK is in a known state 2936 02405 1410 TAD @X1 ; get the next word of the key 2937 02406 7450 SNA ; have we done them all ? 2938 02407 6225 .POPJ ; yes - return success 2939 02410 7041 CIA ; make it negative 2940 02411 6266 CPD ; address main memory now 2941 02412 1411 TAD @X2 ; and compare our key to what's there 2942 02413 0130 AND ZK177 ; (PAL8 likes to set the high bit for ASCII!) 2943 02414 6276 SPD ; (back to panel memory) 2944 02415 7120 STL ; assume that we failed 2945 02416 7640 SZA CLA ; did the key match ? 2946 02417 6225 .POPJ ; nope - return with the LINK set 2947 02420 5204 JMP CKBOO1 ; yes - keep testing... 2948 2949 ; Ok, here it is - the magic key that makes a volume bootable! 2950 02421 BOOKEY: .ASCIZ /BOOT/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 67 B Command - Boot Disk BTS6120.plx 2951 .TITLE B Command - Boot Disk 2952 2953 2954 ; The B command boots, or at least it tries to, either RAM or IDE disk. 2955 ; It can be used with an argument to specify the device to be booted, or 2956 ; without to ask BTS6120 to search for a bootable volume. For example: 2957 ; 2958 ; >B VM - boot device VMA0 2959 ; >B ID - boot device IDA0 2960 ; >B - search VMA0, then IDA0, for a bootstrap 2961 ; 2962 ; If no valid bootsrap can be found, then the message "?Not bootable" is 2963 ; printed. 2964 ; 2965 ; NOTE: It is currently only possible to bootstrap from unit zero for RAM 2966 ; disk, or partition zero in the case of IDE disk. 2967 ; 2968 ; NOTE also - the BOOT command ignores the state of the front panel (if 2969 ; any) RUN/HALT switch. In particular, it doesn't single step if the 2970 ; HALT switch is down when this command is executed. That seems like 2971 ; the most sensible thing. 2972 02426 6205 BOOT: .PUSHJ @ZSPACMP ; get the next non-space character 02427 5510 2973 02430 7650 SNA CLA ; is it the end of the line ? 2974 02431 5252 JMP BOOT1 ; yes - go search for a bootstrap 2975 02432 6205 .PUSHJ @ZBACKUP ; nope - backup to the first letter 02433 5512 2976 02434 6205 .PUSHJ @[NAMENW] ; and read the boot device name 02435 5776 2977 02436 6205 .PUSHJ @ZEOLNXT ; now there has to be an EOL 02437 5514 2978 2979 ; Here if a specific device name is given on the command line... 2980 02440 1375 TAD [BNAMES-1] ; point to the table of boot names 2981 02441 6205 .PUSHJ @[MATCH] ; go call the right boot routine 02442 5774 2982 02443 7430 SZL ; did we find a bootstrap ? 2983 02444 5262 JMP NOBOOT ; nope - print an error message 2984 2985 ; Now do the equivalent of a "ST 5" to start the bootstrap running... 2986 02445 6205 BOOTGO: .PUSHJ @[CLRCPU] ; clear all saved main memory state 02446 5773 2987 02447 1372 TAD [5] ; the secondary bootstrap starts at offset 5 2988 02450 3000 DCA UPC ; ... 2989 02451 5771 JMP @[CONT] ; cross your fingers! 2990 2991 ; Here to search for a bootable device... 2992 02452 6205 BOOT1: .PUSHJ BTVMA0 ; first try booting VMA0 02453 5264 2993 02454 7420 SNL ; did we succeed? 2994 02455 5245 JMP BOOTGO ; yes - go start the bootstrap 2995 02456 6205 .PUSHJ BTIDA0 ; nope - try IDA0 next 02457 5300 2996 02460 7420 SNL ; how about this? 2997 02461 5245 JMP BOOTGO ; yes - use that on instead 2998 2999 ; Here if no bootstrap can be found... 3000 02462 4526 NOBOOT: JMS @ZERROR ; print an error and return to command level 3001 02463 3526 ERRNBT ; ?NO BOOTSTRAP 3002 3003 3004 ; Here to attempt booting VMA0... 3005 02464 4527 BTVMA0: JMS @ZPUSHJ1 ; (cross field call) 3006 02465 0400 RDBOOT ; RAM disk primary bootstrap 3007 02466 6205 .PUSHJ CKBOOT ; is this volume bootable? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 68 B Command - Boot Disk BTS6120.plx 02467 5200 3008 02470 7430 SZL ; skip if yes 3009 02471 6225 .POPJ ; not bootable - just give up 3010 02472 4507 JMS @ZINLMES ; say 3011 02473 4105 VMAMSG ; "-VMA0" 3012 02474 6205 .PUSHJ @ZCRLF ; ... 02475 5506 3013 02476 7100 CLL ; be sure to return success 3014 02477 6225 .POPJ ; ... 3015 3016 3017 ; Here to attempt booting IDA0... 3018 02500 4527 BTIDA0: JMS @ZPUSHJ1 ; (cross field call) 3019 02501 1200 IDBOOT ; IDE disk primary bootstrap 3020 02502 6205 .PUSHJ CKBOOT ; is this volume bootable? 02503 5200 3021 02504 7430 SZL ; skip if yes 3022 02505 6225 .POPJ ; not bootable - just give up 3023 02506 4507 JMS @ZINLMES ; say 3024 02507 4112 IDAMSG ; "-IDA0" 3025 02510 6205 .PUSHJ @ZCRLF ; ... 02511 5506 3026 02512 7100 CLL ; and be sure to return success 3027 02513 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 69 Parse FORMAT Unit/Partition Argument BTS6120.plx 3028 .TITLE Parse FORMAT Unit/Partition Argument 3029 3030 3031 ; This routine will parse the unit/partition number argument for FORMAT. 3032 ; Since this command is little on the dangerous side (it does erase all the 3033 ; data on the disk, after all!), we'll go to the extraordinary length of 3034 ; asking for confirmation before we do anything. Confirmation is nothing 3035 ; more than a single character (we don't wait for a carriage return) - "Y" 3036 ; continues with the format and anything else, including ^C, aborts... 3037 ; 3038 ; Assuming the user confirms, then the unit/partition number will be 3039 ; returned in the AC. If the user aborts, or if there are any syntax 3040 ; errors, then we restart the command scanner and never return. 3041 02514 6205 FMTARG: .PUSHJ @ZOCTNW ; read the unit/partition number 02515 5516 3042 02516 6205 .PUSHJ @ZEOLTST ; that has to be followed by the end of line 02517 5513 3043 02520 4507 JMS @ZINLMES ; say 3044 02521 3743 FCFMSG ; "Format partition/unit " 3045 02522 1065 TAD WORD ; get the partition number once again 3046 02523 3044 DCA VALUE ; TOCT corrupts WORD, 3047 02524 1044 TAD VALUE ; .... so we have to stash it here 3048 02525 6205 .PUSHJ @ZTOCT4S ; and type it out 02526 5502 3049 02527 6205 .PUSHJ @[CONFRM] ; go wait for a "Y" or "y" 02530 5770 3050 02531 7620 SNL CLA ; did he confirm? 3051 02532 5524 JMP @ZRESTA ; no - just abort now 3052 02533 1044 TAD VALUE ; yes he did - return the unit in the AC 3053 02534 6225 .POPJ ; ... 3054 3055 ; Here if the RAM disk unit number is illegal... 3056 02535 4526 NOUNIT: JMS @ZERROR ; ... 3057 02536 3430 ERRILV ; "?Illegal value" 3058 3059 ; This little routine verifies that a hard disk is attached to the system. 3060 ; If there is none, then an error message is printed and the command aborted. 3061 ; HOOK: an extension ROM can intercept this call in order to do its own 3062 ; checking if a disk is installed, e.g. in the case of a system with 3063 ; a storage device on a different interface. 3064 02537 7000 NODISK: NOP 3065 02540 7000 NOP 3066 02541 7000 NOP 3067 02542 6211 CDF 1 ; there's a disk attached 3068 02543 1767 TAD @[DKSIZE] ; ... only if DKSIZE != 0 3069 02544 6201 CDF 0 ; ... 3070 02545 7640 SZA CLA ; skip if there's no disk there 3071 02546 6225 .POPJ ; yes - return now 3072 02547 4526 JMS @ZERROR ; print a message and abort the command 3073 02550 3537 ERRNDK ; "?No disk" 3074 02567 0022 02570 7025 02571 2216 02572 0005 02573 2312 02574 6642 02575 3373 02576 6600 02577 2420 3075 02600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 70 PM Command - Show and Edit Disk Partition Map BTS6120.plx 3076 .TITLE PM Command - Show and Edit Disk Partition Map 3077 3078 3079 ; The PM command allows the default mapping of OS/8 units to IDE disk 3080 ; partitions to be changed. PM accepts two arguments, both of which are 3081 ; optional. The first argument is the OS/8 logical unit number, and the 3082 ; second argument a partition number, in octal. Used without any arguments, 3083 ; the PM command will display a list of all eight OS/8 units and their current 3084 ; mappings. With one argument, PM will display only the mapping for that 3085 ; unit, and with two arguments PM will change the mapping of that unit. 3086 ; 3087 ; >PM u pppp - map OS/8 ID01 unit u to IDE partition pppp 3088 ; >PM u - display the mapping for unit u 3089 ; >PM - display the mapping for all units 3090 ; 3091 02600 6205 PMEDIT: .PUSHJ @ZSPACMP ; get the next non-space character 02601 5510 3092 02602 7650 SNA CLA ; is it the end of the line ? 3093 02603 5241 JMP PMALL ; yes - show the entire map 3094 02604 6205 .PUSHJ @ZBACKUP ; nope - backup and read this character 02605 5512 3095 02606 6205 .PUSHJ @ZOCTNW ; it should be a unit number 02607 5516 3096 02610 1065 TAD WORD ; get the value we read 3097 02611 0377 AND [7770] ; and the unit number must be less than 7 3098 02612 7640 SZA CLA ; ?? 3099 02613 5237 JMP PMEDI1 ; nope - "Illegal value" 3100 02614 1065 TAD WORD ; transfer the unit number 3101 02615 3067 DCA COUNT ; to COUNT for later use 3102 3103 ; See if there's also a partition number on the line... 3104 02616 6205 .PUSHJ @ZSPACM0 ; get the next non-space character 02617 5511 3105 02620 7650 SNA CLA ; is it the end of the line? 3106 02621 5252 JMP PMSHOW ; yes - print the mapping for this unit only 3107 02622 6205 .PUSHJ @ZBACKUP ; nope - read what comes next 02623 5512 3108 02624 6205 .PUSHJ @ZOCTNW ; this should be the partition number 02625 5516 3109 02626 6205 .PUSHJ @ZEOLTST ; and then we have to be at the EOL 02627 5513 3110 3111 ; Here to change the mapping for a specific unit... 3112 02630 1067 TAD COUNT ; get the unit number 3113 02631 1376 TAD [PARMAP-1] ; and make an index into the mapping table 3114 02632 3010 DCA X1 ; ... 3115 02633 1065 TAD WORD ; get the desired mapping 3116 02634 3410 DCA @X1 ; and update the partition table 3117 02635 6222 CIF 2 3118 02636 5775 JMP @[WRPSS] ; store the PM in NVRAM if it exists 3119 ; and we're all done 3120 3121 ; Here if the unit number is illegal... 3122 02637 4526 PMEDI1: JMS @ZERROR ; say 3123 02640 3430 ERRILV ; "?Illegal value" and abort 3124 3125 3126 ; Here to show all eight entries in the entire partition map... 3127 02641 3067 PMALL: DCA COUNT ; start with unit zero 3128 02642 6205 .PUSHJ PMSHOW ; and show the mapping for that unit 02643 5252 3129 02644 2067 ISZ COUNT ; now onto the next one 3130 02645 1067 TAD COUNT ; have we done eight ? 3131 02646 1377 TAD [-10] ; ??? 3132 02647 7640 SZA CLA ; well ? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 71 PM Command - Show and Edit Disk Partition Map BTS6120.plx 3133 02650 5242 JMP PMALL+1 ; nope - keep going 3134 02651 6225 .POPJ ; yes, we can quit now 3135 3136 ; Here to show the mapping for the unit in COUNT... 3137 02652 4507 PMSHOW: JMS @ZINLMES ; say 3138 02653 4065 PM1MSG ; "Unit " 3139 02654 1067 TAD COUNT ; get the selected unit 3140 02655 6205 .PUSHJ @[TDIGIT] ; and type it 02656 5774 3141 02657 4507 JMS @ZINLMES ; now say 3142 02660 4072 PM2MSG ; " mapped to partition " 3143 02661 1067 TAD COUNT ; get the count again 3144 02662 1376 TAD [PARMAP-1] ; and index the partition table 3145 02663 3010 DCA X1 ; ... 3146 02664 1410 TAD @X1 ; get the partition mapped to this unit 3147 02665 5500 JMP @ZTOCT4C ; type it, in octal, and a CRLF PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 72 Disk Formatter, Pass 1 BTS6120.plx 3148 .TITLE Disk Formatter, Pass 1 3149 3150 3151 ; Pass one of the RAM/IDE disk formatter writes every block with a simple 3152 ; test pattern consisting of alternating words filled with the block number 3153 ; and its complement. Although it's not too creative, this pattern does do 3154 ; two things - it guarantees that each block is unique (so we can make sure 3155 ; the disk addresssing is working!) and it does ensure that every bit gets 3156 ; tested with a zero and a one (so we can make sure the data lines are 3157 ; working). 3158 ; 3159 ; This routine expects that a number of memory locations will be initialized 3160 ; before it's called. RECSIZ must contain the negative of the logical record 3161 ; size for the device (-256 for IDE disk or -128 for RAM disk). FMTCNT should 3162 ; contain the negative of the device size, in blocks/pages, and FMTWRP (a 3163 ; location in this routine!) must be initialized with the address of the 3164 ; disk write routine... 3165 02666 4507 FMTP1: JMS @ZINLMES ; say 3166 02667 3763 FM1MSG ; ... "Writing " 3167 02670 6211 CDF 1 ; ... 3168 02671 3537 DCA @ZDKRBN ; reset the current disk block 3169 02672 3536 DCA @ZRDPAGE ; and page numbers 3170 3171 ; Fill the disk buffer with the test pattern... 3172 02673 1071 FMTP11: TAD RECSIZ ; get the negative of the record size 3173 02674 7130 CLL CML RAR ; and divide it by two 3174 02675 3067 DCA COUNT ; since we'll fill the buffer in word pairs 3175 02676 1373 TAD [DSKBUF-1] ; point X1 to the disk buffer 3176 02677 3010 DCA X1 ; ... 3177 02700 6211 CDF 1 ; (the disk buffer is in field 1) 3178 02701 1073 FMTP12: TAD FMTCNT ; get the current block/page number 3179 02702 3410 DCA @X1 ; store that 3180 02703 1073 TAD FMTCNT ; then store its complement 3181 02704 7040 CMA ; ... 3182 02705 3410 DCA @X1 ; in the next word 3183 02706 2067 ISZ COUNT ; have we done the whole buffer? 3184 02707 5301 JMP FMTP12 ; nope - keep filling 3185 02710 6201 CDF 0 ; return to our default field 3186 3187 ; Write the buffer to the disk... 3188 02711 4527 JMS @ZPUSHJ1 ; (cross field call) 3189 02712 2200 PNLBUF ; setup our temporary buffer in field 1 3190 02713 1071 TAD RECSIZ ; pass the record size to the I/O routine 3191 02714 4527 JMS @ZPUSHJ1 ; (cross field call) 3192 02715 FMTWRP: .BLOCK 1 ; modified to either DISKWR or RAMDWR 3193 02716 7430 SZL ; were there any errors ? 3194 02717 5772 JMP @[DIOERR] ; yes - quit now 3195 3196 ; See if we've done the whole disk... 3197 02720 7200 CLA ; ... 3198 02721 2073 ISZ FMTCNT ; increment the page/block counter 3199 02722 7410 SKP ; not done yet - keep going 3200 02723 6225 .POPJ ; all done! 3201 02724 6211 CDF 1 ; disk data lives in field 1 3202 02725 2537 ISZ @ZDKRBN ; increment the disk block number 3203 02726 2536 ISZ @ZRDPAGE ; and the RAM disk page number 3204 02727 6201 CDF 0 ; back to safe ground 3205 3206 ; Print a dot every so often to make a simple "progress bar"... 3207 02730 1071 TAD RECSIZ ; get the current record size 3208 02731 7040 CMA ; and make it a mask for the lower bits 3209 02732 0073 AND FMTCNT ; apply it to the current block/page number 3210 02733 7640 SZA CLA ; ... 3211 02734 5273 JMP FMTP11 ; not time for a dot yet 3212 02735 6205 .PUSHJ @ZTDOT ; print a dot to show our progress PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 73 Disk Formatter, Pass 1 BTS6120.plx 02736 5505 3213 02737 5273 JMP FMTP11 ; and another page or block 3214 02772 3504 02773 7377 02774 7102 02775 0243 02776 0017 02777 7770 3215 03000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 74 Disk Formatter, Pass 2 BTS6120.plx 3216 .TITLE Disk Formatter, Pass 2 3217 3218 3219 ; Pass two of the RAM/IDE disk formatter reads back every block and verifies 3220 ; that the test pattern written by pass 1 is there. If any block doesn't 3221 ; contain the data we expect, then a "Verification error" message will be 3222 ; printed, but verification continues. This routine expects all the same 3223 ; data to be set up in FMTCNT and RECSIZ as Pass 1, and in addition it 3224 ; expects FMTRDP to be initialized with the address of the disk read routine. 3225 03000 4507 FMTP2: JMS @ZINLMES ; say 3226 03001 3772 FM2MSG ; "Verifying" 3227 03002 6211 CDF 1 ; ... 3228 03003 3537 DCA @ZDKRBN ; reset the current disk block 3229 03004 3536 DCA @ZRDPAGE ; and page numbers 3230 03005 6201 CDF 0 ; ... 3231 3232 ; Read the next block/page from the disk... 3233 03006 4527 FMTP21: JMS @ZPUSHJ1 ; (cross field call) 3234 03007 2200 PNLBUF ; setup a temporary disk buffer in panel memory 3235 03010 1071 TAD RECSIZ ; pass the record size to DISKRD 3236 03011 4527 JMS @ZPUSHJ1 ; (cross field call) 3237 03012 FMTRDP: .BLOCK 1 ; gets modified to either DISKRD or RAMDRD! 3238 03013 7430 SZL ; any I/O errors ? 3239 03014 5777 JMP @[DIOERR] ; yes - just give up now 3240 3241 ; Verify that the data in the buffer matches what we wrote... 3242 03015 1071 TAD RECSIZ ; and get the block/page size 3243 03016 7130 CLL CML RAR ; divide it by two 3244 03017 3067 DCA COUNT ; because we'll test in double word pairs 3245 03020 1376 TAD [DSKBUF-1] ; point X1 to the disk buffer 3246 03021 3010 DCA X1 ; ... 3247 03022 6211 CDF 1 ; (disk buffer lives in field 1) 3248 03023 1073 FMTP22: TAD FMTCNT ; get the current block/page number 3249 03024 7041 CIA ; make it negative 3250 03025 1410 TAD @X1 ; and compare to the first word in the buffer 3251 03026 7640 SZA CLA ; it matches, no? 3252 03027 5257 JMP FMTP29 ; no - verify error! 3253 03030 1410 TAD @X1 ; the second word is the complement of the page 3254 03031 1073 TAD FMTCNT ; so that plus this 3255 03032 7001 IAC ; plus 1 should be zero! 3256 03033 7640 SZA CLA ; are we right? 3257 03034 5257 JMP FMTP29 ; no - verify error! 3258 03035 2067 ISZ COUNT ; have we done the whole buffer? 3259 03036 5223 JMP FMTP22 ; nope - keep testing 3260 03037 6201 CDF 0 ; return to our regular field 3261 3262 ; See if we've done the whole disk... 3263 03040 2073 FMTP23: ISZ FMTCNT ; increment the page/block counter 3264 03041 7410 SKP ; not done yet - keep going 3265 03042 6225 .POPJ ; all done! 3266 03043 6211 CDF 1 ; disk data lives in field 1 3267 03044 2537 ISZ @ZDKRBN ; increment the disk block number 3268 03045 2536 ISZ @ZRDPAGE ; and the RAM disk page number 3269 03046 6201 CDF 0 ; back to safe ground 3270 3271 ; Print a dot every so often to make a simple "progress bar"... 3272 03047 1071 TAD RECSIZ ; get the current record size 3273 03050 7040 CMA ; and make it a mask for the lower bits 3274 03051 0073 AND FMTCNT ; apply it to the current block/page number 3275 03052 7640 SZA CLA ; ... 3276 03053 5206 JMP FMTP21 ; not time for a dot yet 3277 03054 6205 .PUSHJ @ZTDOT ; print a dot to show our progress 03055 5505 3278 03056 5206 JMP FMTP21 ; and another page or block 3279 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 75 Disk Formatter, Pass 2 BTS6120.plx 3280 ; Here if one (or more) words don't match.. 3281 03057 6201 FMTP29: CDF 0 ; restore the usual field 3282 03060 6205 .PUSHJ @ZCRLF ; we're in the middle of a line now 03061 5506 3283 03062 4507 JMS @ZINLMES ; so start a new one and print 3284 03063 4010 ERRDSK ; "?Verification error, block/page " 3285 03064 6211 CDF 1 ; (disk data is in field 1) 3286 03065 1537 TAD @ZDKRBN ; get the current block/page number 3287 03066 6201 CDF 0 ; ... 3288 03067 6205 .PUSHJ @ZTOCT4C ; and type it (in octal) 03070 5500 3289 03071 5240 JMP FMTP23 ; better luck with the next block PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 76 DF Command - Format IDE Disk Partition BTS6120.plx 3290 .TITLE DF Command - Format IDE Disk Partition 3291 3292 3293 ; The DF command will "format" an IDE disk partition. The name is a misnomer 3294 ; because there's nothing about an IDE disk that needs formatting in the way 3295 ; a floppy does, but this command does write and then read back every single 3296 ; block of the partition which serves the useful function of testing the disk. 3297 ; It works in two passes - the first pass writes every block with a test 3298 ; pattern, and the second pass reads and verifies every block for the correct 3299 ; data. 3300 ; 3301 ; >DF pppp - format disk partition pppp 3302 ; 3303 03072 6205 DFRMAT: .PUSHJ @[NODISK] ; verify that a hard disk is attached 03073 5775 3304 03074 6205 .PUSHJ @[FMTARG] ; get the partition and ask for confirmation 03075 5774 3305 03076 6211 CDF 1 ; the IDE disk data lives in field one 3306 03077 3773 DCA @[DKPART] ; save the partition number 3307 03100 6201 CDF 0 ; ... 3308 03101 1135 TAD ZM256 ; the record size for IDE disk is 256 words 3309 03102 3071 DCA RECSIZ ; ... 3310 3311 ; Do pass 1... 3312 03103 3073 DCA FMTCNT ; an IDE partition always holds 4096 blocks 3313 03104 1372 TAD [DISKWR] ; point to the correct I/O routine 3314 03105 3771 DCA @[FMTWRP] ; and point pass 1 towards that 3315 03106 6205 .PUSHJ @[FMTP1] ; go do pass 1 03107 5770 3316 3317 ; And do pass 2... 3318 03110 3073 DCA FMTCNT ; reset the block count to 4096 3319 03111 1367 TAD [DISKRD] ; and point pass 2 to the disk read routine 3320 03112 3212 DCA FMTRDP ; ... 3321 03113 6205 .PUSHJ FMTP2 ; and away we go! 03114 5200 3322 3323 ; We've tested the entire disk... 3324 03115 4507 FRDONE: JMS @ZINLMES ; let the operator know we're done 3325 03116 4003 FM3MSG ; "Finished" 3326 03117 5506 JMP @ZCRLF ; finish the line and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 77 RF Command - Format a RAM Disk BTS6120.plx 3327 .TITLE RF Command - Format a RAM Disk 3328 3329 3330 ; The RF command will "format" a RAM disk virtual drive and it's essentially 3331 ; identical to the DF command that formats IDE disks. 3332 ; 3333 ; >RF u - format RAM disk unit u 3334 ; 3335 03120 6205 RFRMAT: .PUSHJ @[FMTARG] ; get the unit and ask for confirmation 03121 5774 3336 03122 6211 CDF 1 ; the RAM disk data lives in field one 3337 03123 3766 DCA @[RDUNIT] ; save the unit 3338 03124 6201 CDF 0 ; ... 3339 03125 4527 JMS @ZPUSHJ1 ; (cross field call) 3340 03126 0713 RAMSEL ; try to select this RAM disk unit 3341 03127 7630 SZL CLA ; was the unit number legal ?? 3342 03130 5765 JMP @[NOUNIT] ; nope - quit while we're ahead! 3343 03131 1134 TAD ZM128 ; the record size for RAM disk is 128 words 3344 03132 3071 DCA RECSIZ ; ... 3345 3346 ; Do pass 1... 3347 03133 6211 CDF 1 ; get the size of this RAM disk unit 3348 03134 1764 TAD @[RAMUSZ] ; which is left here by RAMSEL 3349 03135 3073 DCA FMTCNT ; save it for pass 1 3350 03136 6201 CDF 0 ; ... 3351 03137 1363 TAD [RAMDWR] ; get the correct I/O routine 3352 03140 3771 DCA @[FMTWRP] ; and point pass 1 towards that 3353 03141 6205 .PUSHJ @[FMTP1] ; go do pass 1 03142 5770 3354 3355 ; And do pass 2... 3356 03143 6211 CDF 1 ; get the size of this RAM disk unit 3357 03144 1764 TAD @[RAMUSZ] ; which is left here by RAMSEL 3358 03145 3073 DCA FMTCNT ; save it for pass1 3359 03146 6201 CDF 0 ; ... 3360 03147 1362 TAD [RAMDRD] ; and point pass 2 to the disk read routine 3361 03150 3212 DCA FMTRDP ; ... 3362 03151 6205 .PUSHJ FMTP2 ; and away we go! 03152 5200 3363 3364 ; We've tested the entire disk... 3365 03153 5315 JMP FRDONE ; say "Finished" and we're done! 3366 03162 0407 03163 0420 03164 0045 03165 2535 03166 0024 03167 1214 03170 2666 03171 2715 03172 1244 03173 0020 03174 2514 03175 2537 03176 7377 03177 3504 3367 03200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 78 LP Command - Load Binary Paper Tapes from the Console BTS6120.plx 3368 .TITLE LP Command - Load Binary Paper Tapes from the Console 3369 3370 3371 ; The LP command loads a "paper tape" in standard PDP-8 BIN loader format 3372 ; from the console. If the console is actually an ASR-33 and you actually 3373 ; have a real PDP-8 paper tape, then this will probably even work, but a more 3374 ; likely situation is that you're using a PC with a terminal emulator. In 3375 ; that case the paper tape image can be downloaded from the PC's disk. 3376 ; 3377 ; The loader accepts all standard BIN data frames, including field changes, 3378 ; and correctly calculates and verifies the tape checksum. If the checksum 3379 ; matches then the number of words loaded is printed - otherwise a checksum 3380 ; error message is generated. When initially started, this routine ignores 3381 ; all input until two consectutive leader codes (octal 200) are found - this 3382 ; allows us to ignore any extra ASCII characters from the terminal emulator 3383 ; (such as carriage returns, spaces, etc). 3384 ; 3385 ; Since we're using the real console, the same one that you're typing 3386 ; commands on, for input we have a problem in that we need some way to 3387 ; terminate loading. Control-C won't work since the BIN loader eats all 3388 ; eight bit characters. A hardware reset isn't a good idea, since the POST 3389 ; memory test will erase everything we've loaded. Instead we use a special 3390 ; routine, CONGET, to read characters from the console and this routine has a 3391 ; timeout built in. If we go approximately 5 seconds without any input then 3392 ; the loader is terminated. 3393 03200 6205 CONLOD: .PUSHJ @ZEOLNXT ; this command has no operands 03201 5514 3394 03202 3037 DCA PNLMEM ; files are always lodaded into main memory 3395 3396 ; Look for two consecutive bytes of leader code... 3397 03203 1377 BINLO1: TAD [-2] ; we need two bytes of leader/trailer 3398 03204 3067 DCA COUNT ; ... 3399 03205 6205 BINLO2: .PUSHJ CONGET ; go read a byte of input 03206 5325 3400 03207 1376 TAD [-200] ; is this a leader code ?? 3401 03210 7640 SZA CLA ; ?? 3402 03211 5203 JMP BINLO1 ; no -- keep looking for two 3403 03212 2067 ISZ COUNT ; yes -- is this the second in a row ?? 3404 03213 5205 JMP BINLO2 ; no -- go look for the next one 3405 3406 ; Here after we have 2 bytes of leader -- look for the end of the leader... 3407 03214 6205 BINLO3: .PUSHJ CONGET ; get another byte of data 03215 5325 3408 03216 1376 TAD [-200] ; are we still in the leader ?? 3409 03217 7450 SNA ; ??? 3410 03220 5214 JMP BINLO3 ; yes -- keep looking 3411 03221 1375 TAD [200] ; no -- restore the character 3412 03222 3065 DCA WORD ; and remember it for later 3413 3414 ; Now actually start loading data... 3415 03223 3046 DCA CHKSUM ; start with a zero checksum 3416 03224 1375 TAD [200] ; set the default load address to location 200 3417 03225 3035 DCA ADDR ; ... 3418 03226 3036 DCA ADRFLD ; in field zero 3419 3420 ; Decode the type of the next load record... 3421 03227 7621 BINLO5: CAM ; ... 3422 03230 1065 TAD WORD ; Get the last character we read 3423 03231 0375 AND [200] ; Is this a single byte frame ??? 3424 03232 7640 SZA CLA ; ?? 3425 03233 5301 JMP BINLO7 ; Yes -- this is EOF or a field setting 3426 3427 ; Load a two frame record (either data or an address)... 3428 03234 1065 TAD WORD ; get the first byte back again 3429 03235 3323 DCA BINCH1 ; and remember that PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 79 LP Command - Load Binary Paper Tapes from the Console BTS6120.plx 3430 03236 6205 .PUSHJ CONGET ; then go read the next byte 03237 5325 3431 03240 3324 DCA BINCH2 ; and save that 3432 03241 1323 TAD BINCH1 ; get the first byte 3433 03242 0374 AND [77] ; trim it to just 6 bits 3434 03243 7002 BSW ; put it in the left half 3435 03244 7421 MQL ; and save it in the MQ for now 3436 03245 1324 TAD BINCH2 ; then get the second character 3437 03246 0374 AND [77] ; trim it to 6 bits too 3438 03247 7501 MQA ; and OR it with the first character 3439 03250 3044 DCA VALUE ; remember what we read 3440 3441 ; Determine what to do with this word... 3442 03251 6205 .PUSHJ CONGET ; look ahead one byte 03252 5325 3443 03253 3065 DCA WORD ; save that character 3444 03254 1065 TAD WORD ; and get it back 3445 03255 1376 TAD [-200] ; is this the end of the tape ?? 3446 03256 7650 SNA CLA ; ?? 3447 03257 5314 JMP BINLO8 ; yes -- we read a checksum word 3448 03260 1046 TAD CHKSUM ; no -- checksum the two characters we read 3449 03261 1323 TAD BINCH1 ; ... 3450 03262 1324 TAD BINCH2 ; ... 3451 03263 3046 DCA CHKSUM ; ... 3452 03264 1323 TAD BINCH1 ; then look at the first character 3453 03265 0373 AND [100] ; is this an address or data frame ?? 3454 03266 7640 SZA CLA ; skip if it's data 3455 03267 5276 JMP BINLO6 ; no -- it is an address 3456 3457 ; Load this word of data into memory... 3458 03270 1044 TAD VALUE ; get the word back 3459 03271 6205 .PUSHJ @ZDANDV ; and write it into memory 03272 5523 3460 03273 2035 ISZ ADDR ; automatically advance the address 3461 03274 7000 NOP ; (and ignore any wrap around) 3462 03275 5227 JMP BINLO5 ; then go process the next frame 3463 3464 ; This word is an address... 3465 03276 1044 BINLO6: TAD VALUE ; get the 12 bits of data 3466 03277 3035 DCA ADDR ; and change to that address 3467 03300 5227 JMP BINLO5 ; then go process the next frame 3468 3469 ; Here of the current frame is a field setting... 3470 03301 1065 BINLO7: TAD WORD ; get the last character back again 3471 03302 0373 AND [100] ; see if it is really a field frame 3472 03303 7650 SNA CLA ; ??? 3473 03304 5314 JMP BINLO8 ; no -- treat it like a trailer code 3474 03305 1065 TAD WORD ; get the field back 3475 03306 0131 AND ZK70 ; we only want these bits 3476 03307 3036 DCA ADRFLD ; and change to the selected field 3477 03310 6205 .PUSHJ CONGET ; Then look ahead one byte 03311 5325 3478 03312 3065 DCA WORD ; ... 3479 03313 5227 JMP BINLO5 ; and go process that frame 3480 3481 ; Here when we find the checksum byte... 3482 03314 1044 BINLO8: TAD VALUE ; get the checksum byte 3483 03315 7041 CIA ; make it negative 3484 03316 1046 TAD CHKSUM ; and add it to our checksum 3485 03317 3046 DCA CHKSUM ; this should leave zero 3486 03320 6205 .PUSHJ @[TCKSUM] ; go type the checksum and return 03321 5772 3487 03322 5203 JMP BINLO1 3488 3489 ; Temporary storage for BIN loader routine... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 80 LP Command - Load Binary Paper Tapes from the Console BTS6120.plx 3490 03323 BINCH1: .BLOCK 1 ; the first of a two character frame 3491 03324 BINCH2: .BLOCK 1 ; the second of a two character frame PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 81 Paper Tape Console Input Routine BTS6120.plx 3492 .TITLE Paper Tape Console Input Routine 3493 3494 3495 ; This routine will read a character from the console, waiting if there is 3496 ; none ready right now, and with a timeout if one doesn't arrive soon. It is 3497 ; intended to be used only with the paper tape binary loader routine, and most 3498 ; "textual" input should be done via the INCHRS or INCHWL routines. Since the 3499 ; user cannot type control-C to abort the paper tape loader (data is being read 3500 ; from the console, remember ?) this routine provides a timeout feature to 3501 ; prevent the monitor from becoming 'hung'. If no character is received from 3502 ; the console in approximately 10 seconds, a control-C is simulated by jumping 3503 ; to RESTA. 3504 0310 FTCONT=200. ; approximately 10 seconds with a 4.9152Mhz clock 3505 3506 03325 7200 CONGET: CLA ; ... 3507 03326 1371 TAD [-FTCONT] ; get the console timeout time 3508 03327 3055 DCA IRMA ; and set up a counter 3509 3510 ; Try to read a character... 3511 03330 6031 CONGE1: KSF ; is there a character there ??? 3512 03331 5335 JMP CONGE2 ; no -- check the timer 3513 03332 7200 CLA ; yes -- clear the timer 3514 03333 6036 KRB ; and get the character 3515 03334 6225 .POPJ ; then return that 3516 3517 ; Here to keep the timeout counter. The loop between CONGE1 and CONGE2 3518 ; requires 56 states, or approximately .1835 seconds at 2.5Mhz. This is 3519 ; executed FTCONT times for the overall timeout. 3520 03335 7001 CONGE2: IAC ; increment the timer 3521 03336 7440 SZA ; has it counted to 4096 ??? 3522 03337 5330 JMP CONGE1 ; no -- keep waiting 3523 03340 2055 ISZ IRMA ; yes -- have we waited long enough ?? 3524 03341 5330 JMP CONGE1 ; no -- wait a little longer 3525 03342 7325 NL0003 ; yes -- simulate a control-C 3526 03343 6205 .PUSHJ @ZOUTCHR ; echo ^C 03344 5474 3527 03345 5524 JMP @ZRESTA ; and restart 3528 03371 7470 03372 1472 03373 0100 03374 0077 03375 0200 03376 7600 03377 7776 3529 03400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 82 RD and DD Commands - Dump Disk (RAM and IDE) Records BTS6120.plx 3530 .TITLE RD and DD Commands - Dump Disk (RAM and IDE) Records 3531 3532 3533 ; These commands dump one or more disk records, in octal, to the console. 3534 ; What you get from DP is exactly how the OS/8 device driver sees the disk 3535 ; data. Each command accepts one, two or three parameters. The first is unit 3536 ; number for RAM Disk (RD) commands, or the partition number for IDE Disk (DD) 3537 ; commands. The second parameter is the number of the block to be dumped, in 3538 ; octal. If this number is omitted then the ENTIRE disk will be dumped which, 3539 ; although legal, will take quite a while! The third parameter is the count 3540 ; of pages (for RAM Disk) or blocks (for IDE disk) to be dumped and, if 3541 ; omitted, this defaults to 1. For example: 3542 ; 3543 ; >RD 0 0 - dump only page 0 (the boot block) of RAM disk unit 0 3544 ; >DD 2 100 - dump only page 100 (octal) of IDE partition 2 3545 ; >RD 1 100 77 - dump 64 (77 octal) pages of unit 1 from 100 to 177 3546 ; >DD 0 - dump ALL of IDE partition zero (4095 blocks!) 3547 ; 3548 3549 ; Enter here for the RD command... 3550 03400 1377 RDDUMP: TAD [RAMDRD] ; point to the RAM disk read routine 3551 03401 3267 DCA RDPTR ; modify the code to use that 3552 03402 1134 TAD ZM128 ; get the record size for RAM disk 3553 03403 3071 DCA RECSIZ ; and save that 3554 03404 5213 JMP PARSDX ; fall into the regular code now 3555 3556 ; And here for the DD command... 3557 03405 6205 DDDUMP: .PUSHJ @[NODISK] ; verify that a hard disk exists 03406 5776 3558 03407 1375 TAD [DISKRD] ; point to the IDE disk read routine 3559 03410 3267 DCA RDPTR ; and use that instead 3560 03411 1135 TAD ZM256 ; IDE disk uses 256 word records 3561 03412 3071 DCA RECSIZ ; ... 3562 3563 ; Parse the argument lists for either command... 3564 03413 6205 PARSDX: .PUSHJ @ZOCTNW ; read the unit/partition number (required) 03414 5516 3565 03415 6211 CDF 1 ; all disk data lives in field 1 3566 03416 1065 TAD WORD ; get what we found 3567 03417 3774 DCA @[DKPART] ; save both the partition number 3568 03420 1065 TAD WORD ; ... 3569 03421 3773 DCA @[RDUNIT] ; and the unit number 3570 03422 3537 DCA @ZDKRBN ; set the default starting block/page to zero 3571 03423 3536 DCA @ZRDPAGE ; ... 3572 03424 6201 CDF 0 ; back to the current field 3573 03425 3072 DCA RECCNT ; make the default record count the whole disk 3574 3575 ; See if there's a starting page number on the command line... 3576 03426 6205 .PUSHJ @ZSPACM0 ; are there any more characters in the command? 03427 5511 3577 03430 7650 SNA CLA ; skip if there are 3578 03431 5263 JMP DDUMP1 ; nope - start dumping now 3579 03432 6205 .PUSHJ @ZBACKUP ; yes - re-read the character 03433 5512 3580 03434 6205 .PUSHJ @ZOCTNW ; and read the page/block number 03435 5516 3581 03436 6211 CDF 1 ; back to field 1 3582 03437 1065 TAD WORD ; get the starting block/page number 3583 03440 3537 DCA @ZDKRBN ; and save it for both RAM disk and IDE disk 3584 03441 1065 TAD WORD ; ... 3585 03442 3536 DCA @ZRDPAGE ; ... 3586 03443 6201 CDF 0 ; back to our field 3587 03444 7240 NLM1 ; now the default record count is one 3588 03445 3072 DCA RECCNT ; ... 3589 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 83 RD and DD Commands - Dump Disk (RAM and IDE) Records BTS6120.plx 3590 ; See if there's a page/block count too.. 3591 03446 6205 .PUSHJ @ZSPACM0 ; still more characters? 03447 5511 3592 03450 7650 SNA CLA ; skip if there are 3593 03451 5263 JMP DDUMP1 ; nope - start dumping now 3594 03452 6205 .PUSHJ @ZBACKUP ; yes - re-read the character 03453 5512 3595 03454 6205 .PUSHJ @ZOCTNW ; and read the page count 03455 5516 3596 03456 1065 TAD WORD ; ... 3597 03457 7041 CIA ; make it negative for ISZ 3598 03460 3072 DCA RECCNT ; and save the count 3599 03461 6205 .PUSHJ @ZEOLTST ; finally, this has to be the end of the line 03462 5513 3600 3601 ; Read a page from the disk into the panel memory buffer and dump it... 3602 03463 4527 DDUMP1: JMS @ZPUSHJ1 ; (call field 1 routine) 3603 03464 2200 PNLBUF ; set the disk buffer to DSKBUF 3604 03465 1071 TAD RECSIZ ; pass the record size to the I/O routine 3605 03466 4527 JMS @ZPUSHJ1 ; (cross field call) 3606 03467 RDPTR: .BLOCK 1 ; gets overwritten with DISKRD or RAMDRD! 3607 03470 7430 SZL ; were there any errors detected ? 3608 03471 5304 JMP DIOERR ; yes - report it and quit 3609 03472 1071 TAD RECSIZ ; nope - get the size of this record 3610 03473 6205 .PUSHJ @[DDBUF] ; and go dump the DSKBUF 03474 5772 3611 03475 6211 CDF 1 ; disk data lives in field 1 3612 03476 2537 ISZ @ZDKRBN ; increment both the IDE block 3613 03477 2536 ISZ @ZRDPAGE ; and RAM disk page 3614 03500 6201 CDF 0 ; ... 3615 03501 2072 ISZ RECCNT ; have we done all we need to? 3616 03502 5263 JMP DDUMP1 ; nope - go dump another one 3617 03503 6225 .POPJ ; yes - we're done (finally!!) 3618 3619 ; Here if a disk I/O error occurs... 3620 03504 6201 DIOERR: CDF 0 ; just in case 3621 03505 3044 DCA VALUE ; save the error code for a minute 3622 03506 4507 JMS @ZINLMES ; say 3623 03507 3502 ERRDIO ; "?I/O Error " 3624 03510 1044 TAD VALUE ; get the error status 3625 03511 6205 .PUSHJ @ZTOCT4M ; type it and a CRLF 03512 5501 3626 ; and abort this command completely PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 84 RL and DL Commands - Load Disk (RAM and IDE) Records BTS6120.plx 3627 .TITLE RL and DL Commands - Load Disk (RAM and IDE) Records 3628 3629 3630 ; The DL and RL commands allow a disk to be downloaded over the console 3631 ; serial port. The format of the data expected is identical that that 3632 ; generated by the RD and DD (dump RAM/IDE disk) commands, which makes it 3633 ; possible to upload a disk image to the PC and then later download the same 3634 ; image back to the SBC6120. Since all the data is simple printing ASCII 3635 ; text, any terminal emulator program can be used to capture and replay the 3636 ; data will suffice. 3637 ; 3638 ; >RL u - download data to RAM disk unit u 3639 ; >DL pppp - download data to IDE disk partition pppp 3640 ; >FL - download data to Flash ROM 3641 3642 ; Enter here for the RL command... 3643 03513 1371 RLLOAD: TAD [RAMDWR] ; point to the RAM disk write routine 3644 03514 3354 DCA WRPTR ; modify the code to use that 3645 03515 1134 TAD ZM128 ; set the record (page) size for RAM disk 3646 03516 3071 DCA RECSIZ ; ... 3647 03517 5326 JMP DLOAD ; fall into the regular code 3648 3649 ; Enter here for the DL command... 3650 03520 6205 DLLOAD: .PUSHJ @[NODISK] ; verify that a hard disk is attached 03521 5776 3651 03522 1370 TAD [DISKWR] ; this time use the IDE disk write routine 3652 03523 3354 DCA WRPTR ; ... 3653 03524 1135 TAD ZM256 ; and the record (block) size is 256 3654 03525 3071 DCA RECSIZ ; ... 3655 3656 ; Parse the argument for the DL and RL commands... 3657 03526 6205 DLOAD: .PUSHJ @ZOCTNW ; read the unit/partition number (required) 03527 5516 3658 03530 6205 .PUSHJ @ZEOLTST ; that has to be followed by the end of line 03531 5513 3659 03532 6211 CDF 1 ; all disk data lives in field 1 3660 03533 1065 TAD WORD ; get the number entered 3661 03534 3773 DCA @[RDUNIT] ; and set the RAM disk unit number 3662 03535 1065 TAD WORD ; ... 3663 03536 3774 DCA @[DKPART] ; and the IDE disk partition number 3664 03537 6201 CDF 0 ; back to our field now 3665 3666 ; Here to read another disk page of data from the host... 3667 03540 1071 DLOAD1: TAD RECSIZ ; pass the block size in the AC 3668 03541 6205 .PUSHJ @[LDBUF] ; load the disk buffer from the serial port 03542 5767 3669 03543 6211 CDF 1 ; (disk data lives in field 1) 3670 03544 3537 DCA @ZDKRBN ; save the address of the block we read 3671 03545 1537 TAD @ZDKRBN ; ... 3672 03546 3536 DCA @ZRDPAGE ; and the page number too 3673 03547 6201 CDF 0 ; (back to our field now) 3674 03550 4527 JMS @ZPUSHJ1 ; (call field 1 routine) 3675 03551 2200 PNLBUF ; set the disk buffer to DSKBUF 3676 03552 1071 TAD RECSIZ ; pass the record size to the I/O routine 3677 03553 4527 JMS @ZPUSHJ1 ; (call a field 1 routine) 3678 03554 WRPTR: .BLOCK 1 ; gets modified to DISKWR, RAMDWR or ROMWR 3679 03555 7430 SZL ; were there any I/O errors? 3680 03556 5304 JMP DIOERR ; yes - go report that and quit 3681 03557 5340 JMP DLOAD1 ; go read another page 3682 03567 3653 03570 1244 03571 0420 03572 3600 03573 0024 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 85 RL and DL Commands - Load Disk (RAM and IDE) Records BTS6120.plx 03574 0020 03575 1214 03576 2537 03577 0407 3683 03600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 86 Dump Disk Buffer on Console BTS6120.plx 3684 .TITLE Dump Disk Buffer on Console 3685 3686 3687 ; This routine will dump the contents of DSKBUF on the console in ASCII. 3688 ; For each block dumped the output format consists of 33 lines of data, where 3689 ; the first 32 lines contain a disk address in the format "." 3690 ; (e.g. "0122.0160" is word 160 (octal) of block 122 (octal)) followed by 8 3691 ; words of data, also in octal. The 33rd line contains just a single octal 3692 ; number, a checksum of all 256 words in the block. 3693 ; 3694 ; This format is exactly the same input that's accepted by the LDBUF, which 3695 ; allows you to capture the output of a disk dump on a PC terminal emulator 3696 ; and then download the same data later to a different disk. This is the 3697 ; primary motivation for the checksum - it isn't too useful to humans, but 3698 ; it will guard against errors in the upload/download procedure. 3699 ; 3700 ; This routine should be called with the number of words to dump in the 3701 ; AC, which will normally be either -256 (to dump an IDE block) or -128 3702 ; (for a RAM disk page). 3703 03600 3252 DDBUF: DCA DDCNT ; save the count of words to dump 3704 03601 3067 DCA COUNT ; and clear the current word count 3705 03602 1377 TAD [DSKBUF-1] ; set up X1 to point to the buffer 3706 03603 3010 DCA X1 ; ... 3707 03604 3046 DCA CHKSUM ; and clear the checksum 3708 3709 ; Start a new line of data... 3710 03605 6211 DDBUF2: CDF 1 ; ... 3711 03606 1537 TAD @ZDKRBN ; get the page/block number we're dumping 3712 03607 6201 CDF 0 ; ... 3713 03610 6205 .PUSHJ @ZTOCT4 ; type it in octal 03611 5477 3714 03612 6205 .PUSHJ @ZTDOT ; then type the separator 03613 5505 3715 03614 1067 TAD COUNT ; then type the offset 3716 03615 6205 .PUSHJ @ZTOCT3 ; ... 03616 5503 3717 03617 6205 .PUSHJ @[TSLASH] ; another separator character 03620 5776 3718 03621 6205 .PUSHJ @ZTSPACE ; ... 03622 5475 3719 3720 ; Dump eight words of data, in octal... 3721 03623 6211 DDBUF3: CDF 1 ; the disk buffer is in field 1 3722 03624 1410 TAD @X1 ; get another word 3723 03625 6201 CDF 0 ; and go back to our field 3724 03626 3044 DCA VALUE ; save it for a minute 3725 03627 1044 TAD VALUE ; get it back 3726 03630 1046 TAD CHKSUM ; and accumulate a checksum 3727 03631 3046 DCA CHKSUM ; ... 3728 03632 1044 TAD VALUE ; now we're ready to type the data 3729 03633 6205 .PUSHJ @ZTOCT4S ; in octal, with a space 03634 5502 3730 03635 2067 ISZ COUNT ; count the number we've done 3731 03636 1067 TAD COUNT ; ... 3732 03637 0132 AND ZK7 ; have we done a complete row of eight? 3733 03640 7640 SZA CLA ; ??? 3734 03641 5223 JMP DDBUF3 ; no - keep going 3735 3736 ; Here after we've finished a line of eight data words... 3737 03642 6205 .PUSHJ @ZCRLF ; start a new line 03643 5506 3738 03644 1067 TAD COUNT ; see if we've done the whole page/block 3739 03645 1252 TAD DDCNT ; compare to the block size 3740 03646 7640 SZA CLA ; ??? 3741 03647 5205 JMP DDBUF2 ; not there yet - keep dumping PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 87 Dump Disk Buffer on Console BTS6120.plx 3742 03650 1046 TAD CHKSUM ; type just the checksum 3743 03651 5500 JMP @ZTOCT4C ; in octal, with a CRLF, and we're done 3744 3745 3746 ; Local storage for DDBUF... 3747 03652 DDCNT: .BLOCK 1 ; the number of words in this buffer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 88 Load Disk Buffer from Console BTS6120.plx 3748 .TITLE Load Disk Buffer from Console 3749 3750 3751 ; This routine loads the disk buffer with data from a disk block image 3752 ; transmitted over the console port. The format of the data expected is 3753 ; identical that that generated by the DDBUF routine, which makes it possible 3754 ; to upload a disk image to the PC and then later download the same image back 3755 ; to the SBC6120 with DL. Since all the data is simple printing ASCII text, 3756 ; any terminal emulator program can be used to capture and replay the data. 3757 ; 3758 ; LDBUF prompts for each line of data with a ":", and most terminal emulator 3759 ; programs for the PC can be set to look for this prompting character before 3760 ; transmitting the next line. This eliminates the need to insert fixed delays 3761 ; to avoid overrunning the SBC6120. Since LDBUF reads only printing ASCII 3762 ; characters, a download can be aborted at any time just by typing a control-C 3763 ; and there's no need for a timeout the way there is with loading paper tape 3764 ; images. 3765 ; 3766 ; The expected block size, either -128. for RAM disk or -256. for IDE disk, 3767 ; should be passed in the AC. The data read is left in DSKBUF, and the 3768 ; page/block number, extracted from the data, is left in LDPAGE. Note that 3769 ; in the event a checksum or syntax error is found, LDBUF prints an error 3770 ; message and restarts the command scanner. In that case control never 3771 ; returns to the caller! 3772 03653 3252 LDBUF: DCA DDCNT ; save the expected block size 3773 03654 1377 TAD [DSKBUF-1] ; initialize X1 to point at our buffer 3774 03655 3010 DCA X1 ; ... 3775 03656 3067 DCA COUNT ; count the data words read here 3776 03657 7240 STA ; the current disk page is unknown 3777 03660 3370 DCA LDPAGE ; ... 3778 03661 3046 DCA CHKSUM ; clear the checksum accumulator 3779 3780 ; Read the next line of data... 3781 03662 1375 LDBUF2: TAD [":"] ; prompt for data with a ":" 3782 03663 6205 .PUSHJ @[INCHWL] ; initialize the line input routine 03664 5774 3783 03665 6205 LDBU20: .PUSHJ @[INCHW1] ; read another character into the buffer 03666 5773 3784 03667 7650 SNA CLA ; EOL? 3785 03670 5265 JMP LDBU20 ; nope - keep reading 3786 03671 1067 TAD COUNT ; see how many words we've read so far 3787 03672 1252 TAD DDCNT ; is it time for the checksum? 3788 03673 7650 SNA CLA ; ??? 3789 03674 5352 JMP LDBUF5 ; yes - go parse a checksum record 3790 3791 ; First parse the disk page number and offset. The offset has to match the 3792 ; number of words we've already read, but the disk address is slightly more 3793 ; complicated. For the first data record in a page we allow the address to 3794 ; be anything, and that tells us which disk page is to be written. Each data 3795 ; record after that up to the end of the page has to have the same disk 3796 ; address as the first one. This allows disk pages to be loaded in any random 3797 ; order and, more importantly, it allows unused pages to be skipped. 3798 03675 6205 .PUSHJ @ZOCTNW ; go read an octal number 03676 5516 3799 03677 1065 TAD WORD ; get the value we scanned 3800 03700 7041 CIA ; compare it to LDPAGE 3801 03701 1370 TAD LDPAGE ; ??? 3802 03702 7650 SNA CLA ; do they match ? 3803 03703 5310 JMP LDBUF3 ; yes - all is well 3804 03704 2370 ISZ LDPAGE ; no - is this the first data record? 3805 03705 5525 JMP @ZCOMERR ; not that either - the data is corrupt 3806 03706 1065 TAD WORD ; yes - just use this page number without 3807 03707 3370 DCA LDPAGE ; ... question 3808 03710 1050 LDBUF3: TAD SAVCHR ; get the separator character 3809 03711 1372 TAD [-"."] ; it has to be a "." PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 89 Load Disk Buffer from Console BTS6120.plx 3810 03712 7640 SZA CLA ; ??? 3811 03713 5525 JMP @ZCOMERR ; nope - bad load format 3812 03714 6205 .PUSHJ @ZOCTNW ; now read the relative offset within the page 03715 5516 3813 03716 1065 TAD WORD ; ... 3814 03717 7041 CIA ; it has to match our data count 3815 03720 1067 TAD COUNT ; does it? 3816 03721 7640 SZA CLA ; ??? 3817 03722 5525 JMP @ZCOMERR ; nope - more bad data 3818 03723 1050 TAD SAVCHR ; one last test 3819 03724 1371 TAD [-"/"] ; the separator this time has to be a slash 3820 03725 7640 SZA CLA ; ??? 3821 03726 5525 JMP @ZCOMERR ; another corrupted data record 3822 3823 ; Now read the rest of the data record, which should consist of exactly 3824 ; eight data words, in octal... 3825 03727 6205 LDBUF4: .PUSHJ @ZOCTNW ; scan the next data word 03730 5516 3826 03731 1065 TAD WORD ; get the value we read 3827 03732 6211 CDF 1 ; remember that the disk buffer is in field 1 3828 03733 3410 DCA @X1 ; and store the data word 3829 03734 1065 TAD WORD ; accumulate a checksum of the data words 3830 03735 1046 TAD CHKSUM ; ... we read 3831 03736 3046 DCA CHKSUM ; ... 3832 03737 6201 CDF 0 ; back to home ground 3833 03740 2067 ISZ COUNT ; count the number of words we've read 3834 03741 1067 TAD COUNT ; let's have a look at it 3835 03742 0132 AND ZK7 ; have we read exactly eight words? 3836 03743 7640 SZA CLA ; skip if we have 3837 03744 5327 JMP LDBUF4 ; no - go read another data word 3838 03745 6205 .PUSHJ @ZGET ; yes - after eight data words 03746 5515 3839 03747 7640 SZA CLA ; ... the next thing should be the EOL 3840 03750 5525 JMP @ZCOMERR ; not EOL - this data is corrupted somehow 3841 03751 5262 JMP LDBUF2 ; this is the EOL - go read another record 3842 3843 ; We get here when we're read 128 or 256 words of data - the next thing we 3844 ; expect to find is a checksum record, which is a single octal number all by 3845 ; itself. This has to match the checksum we've calculated or the data is 3846 ; corrupted. 3847 03752 6205 LDBUF5: .PUSHJ @ZOCTNW ; scan an octal value 03753 5516 3848 03754 1065 TAD WORD ; and get what we found 3849 03755 7041 CIA ; ... 3850 03756 1046 TAD CHKSUM ; compare it to the checksum we accumulated 3851 03757 7640 SZA CLA ; they have to be the same! 3852 03760 5366 JMP DERCKS ; they aren't - bad checksum for data 3853 03761 1050 TAD SAVCHR ; get the next character 3854 03762 7640 SZA CLA ; it has to be the EOL 3855 03763 5525 JMP @ZCOMERR ; no - the syntax of this record is wrong 3856 3857 ; The checksum matches - all is well! 3858 03764 1370 TAD LDPAGE ; return the page number in the AC 3859 03765 6225 .POPJ ; ... 3860 3861 ; Here if the data checksum doesn't match... 3862 03766 4526 DERCKS: JMS @ZERROR ; print a message and restart 3863 03767 3513 ERRCKS ; ?DATA CHECKSUM MISMATCH 3864 3865 ; Local storage for LDBUF... 3866 03770 LDPAGE: .BLOCK 1 ; page number being read 3867 03771 7721 03772 7722 03773 7210 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 90 Load Disk Buffer from Console BTS6120.plx 03774 7200 03775 0072 03776 7074 03777 7377 3868 04000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 91 PC Command - Copy an IDE Disk Partition BTS6120.plx 3869 .TITLE PC Command - Copy an IDE Disk Partition 3870 3871 3872 ; The PC command will copy an entire disk partition to another partition. 3873 ; It's a convenient way to create backups of OS/8 partitions, especially since 3874 ; most modern IDE drives have room for thousands of OS/8 partitions! 3875 ; 3876 ; The PE command will compare two partitions, especially useful after a PC. 3877 ; Due to lack of space for another disk buffer the comparison is done by 3878 ; generating a checksum, unfortunately. 3879 ; 3880 ; >PC ssss dddd - copy IDE partition ssss to partition dddd 3881 ; >PE ssss dddd - compare IDE partition ssss to partition dddd 3882 ; 3883 3884 ; common function to get params 3885 04000 6205 GETPP: .PUSHJ @ZOCTNW ; read the source partition number 04001 5516 3886 04002 1065 TAD WORD ; ... 3887 04003 3040 DCA CPYSRC ; ... 3888 04004 6205 .PUSHJ @[SPATST] ; the next character has to be a space 04005 5777 3889 04006 6205 .PUSHJ @ZOCTNW ; then read the destination partition 04007 5516 3890 04010 1065 TAD WORD ; ... 3891 04011 3041 DCA CPYDST ; ... 3892 04012 5513 JMP @ZEOLTST ; that'd better be all there is 3893 3894 04013 6205 PCOMP: .PUSHJ GETPP 04014 5200 3895 04015 4507 JMS @ZINLMES ; say 3896 04016 3772 CE1MSG ; ... "Verifying " 3897 04017 1376 TAD [PCOPYE] ; operation will be compare block 3898 04020 3035 DCA ADDR ; 3899 04021 5241 JMP PCOPY0 3900 3901 04022 6205 PCOPY: .PUSHJ GETPP 04023 5200 3902 3903 ; Ask for confirmation before overwriting the destination partition... 3904 04024 4507 JMS @ZINLMES ; say 3905 04025 4037 CCFMSG ; "Overwrite partition/unit " 3906 04026 1041 TAD CPYDST ; and then type the partition number 3907 04027 6205 .PUSHJ @ZTOCT4S ; ... 04030 5502 3908 04031 6205 .PUSHJ @[CONFRM] ; then wait for a "Y" or "N" 04032 5775 3909 04033 7620 SNL CLA ; did he answer yes??? 3910 04034 5524 JMP @ZRESTA ; nope - just quit now 3911 3912 ; Prepare to begin copying... 3913 04035 4507 JMS @ZINLMES ; say 3914 04036 4056 CP1MSG ; ... "Copying " 3915 04037 1374 TAD [PCOPYW] ; operation will be write block 3916 04040 3035 DCA ADDR ; 3917 3918 04041 6211 PCOPY0: CDF 1 ; reset the current block number 3919 04042 3537 DCA @ZDKRBN ; ... 3920 04043 6201 CDF 0 ; ... 3921 3922 ; Read the next block from the SRC partition... 3923 04044 4527 PCOPY1: JMS @ZPUSHJ1 ; (cross field call) 3924 04045 2200 PNLBUF ; setup a temporary disk buffer in panel memory 3925 04046 1040 TAD CPYSRC ; get the source partition 3926 04047 6211 CDF 1 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 92 PC Command - Copy an IDE Disk Partition BTS6120.plx 3927 04050 3773 DCA @[DKPART] ; and point DISKRD there 3928 04051 6201 CDF 0 ; ... 3929 04052 1135 TAD ZM256 ; the IDE record size is always 256 words 3930 04053 4527 JMS @ZPUSHJ1 ; (cross field call) 3931 04054 1214 DISKRD ; and go read a block from the disk 3932 04055 7430 SZL ; disk error ?? 3933 04056 5772 JMP @[DIOERR] ; yes - go report it and give up 3934 3935 04057 6205 .PUSHJ @ADDR ; call the operation 04060 5435 3936 3937 ; Print a dot every so often to make a simple "progress bar"... 3938 04061 6211 PCOPY3: CDF 1 ; ... 3939 04062 2771 ISZ @[DKRBN] ; increment the block number 3940 04063 7410 SKP ; still more to go 3941 04064 5276 JMP PCOPY4 ; we've done all 4096 blocks! 3942 04065 1135 TAD ZM256 ; the format command uses the record size as 3943 04066 7040 CMA ; a mask for printing the progress bar 3944 04067 0771 AND @[DKRBN] ; and so we will too 3945 04070 6201 CDF 0 ; ... 3946 04071 7640 SZA CLA ; time for another dot?? 3947 04072 5244 JMP PCOPY1 ; nope - just keep copying 3948 04073 6205 .PUSHJ @ZTDOT ; print a dot to show our progress 04074 5505 3949 04075 5244 JMP PCOPY1 ; and another page or block 3950 3951 ; All done... 3952 04076 6201 PCOPY4: CDF 0 ; ... 3953 04077 4507 JMS @ZINLMES ; say 3954 04100 4003 CP2MSG ; " Done" 3955 04101 5506 JMP @ZCRLF ; and that's all! 3956 3957 ; Operation: write it to the destination... 3958 04102 4527 PCOPYW: JMS @ZPUSHJ1 ; (cross field call) 3959 04103 2200 PNLBUF ; setup the panel memory disk buffer 3960 04104 1041 TAD CPYDST ; change DKPART to the destination partition 3961 04105 6211 CDF 1 ; ... 3962 04106 3773 DCA @[DKPART] ; ... 3963 04107 6201 CDF 0 ; ... 3964 04110 1135 TAD ZM256 ; load the record size for DISKWR 3965 04111 4527 JMS @ZPUSHJ1 ; (cross field call) 3966 04112 1244 DISKWR ; and go write a block to the disk 3967 04113 7430 SZL ; any disk errors? 3968 04114 5772 JMP @[DIOERR] ; yes - give up 3969 04115 6225 .POPJ 3970 3971 ; Operation: compare it to the other partition 3972 ; (1) checksum the disk buffer 3973 04116 6205 PCOPYE: .PUSHJ DBCHKS 04117 5353 3974 04120 3046 DCA CHKSUM 3975 ; (2) read the other partition's block 3976 04121 4527 JMS @ZPUSHJ1 ; (cross field call) 3977 04122 2200 PNLBUF ; setup the panel memory disk buffer 3978 04123 1041 TAD CPYDST ; change DKPART to the destination partition 3979 04124 6211 CDF 1 ; ... 3980 04125 3773 DCA @[DKPART] ; ... 3981 04126 6201 CDF 0 ; ... 3982 04127 1135 TAD ZM256 ; load the record size for DISKWR 3983 04130 4527 JMS @ZPUSHJ1 ; (cross field call) 3984 04131 1214 DISKRD ; and go read a block from the disk 3985 04132 7430 SZL ; any disk errors? 3986 04133 5772 JMP @[DIOERR] ; yes - give up 3987 ; (3) checksum that block 3988 04134 6205 .PUSHJ DBCHKS PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 93 PC Command - Copy an IDE Disk Partition BTS6120.plx 04135 5353 3989 ; (4) make sure they're equal 3990 04136 7041 CIA 3991 04137 1046 TAD CHKSUM 3992 04140 7450 SNA 3993 04141 6225 .POPJ ; alles ganz gut 3994 ; (5) if they weren't equal, report that 3995 04142 6205 .PUSHJ @ZCRLF ; we're in the middle of a line now 04143 5506 3996 04144 4507 JMS @ZINLMES ; so start a new one and print 3997 04145 4010 ERRDSK ; "?Verification error, block/page " 3998 04146 6211 CDF 1 ; (disk data is in field 1) 3999 04147 1537 TAD @ZDKRBN ; get the current block/page number 4000 04150 6201 CDF 0 ; ... 4001 04151 6205 .PUSHJ @ZTOCT4C ; and type it (in octal) 04152 5500 4002 4003 04153 1370 DBCHKS: TAD [DSKBUF-1] ; point to the disk buffer 4004 04154 3010 DCA X1 4005 04155 1367 TAD [-256.] ; and it's 256 words long 4006 04156 3067 DCA COUNT 4007 04157 6211 CDF 1 4008 04160 1410 PCCHK1: TAD @X1 4009 04161 2067 ISZ COUNT 4010 04162 5360 JMP PCCHK1 4011 04163 6201 CDF 0 4012 04164 6225 .POPJ 4013 04167 7400 04170 7377 04171 0021 04172 3504 04173 0020 04174 4102 04175 7025 04176 4116 04177 6124 4014 04200 .PAGE 4015 .TITLE Initialize Terminal, Breakpoint, Partition Map, etc 4016 4017 4018 04200 1377 RAMINIT: TAD [80.] ; the default terminal width is 80 4019 04201 3030 DCA WIDTH ; ... 4020 04202 3031 DCA LENGTH ; and automatic XOFF is disabled 4021 04203 6205 .PUSHJ @[CLRCPU] ; clear the saved user context 04204 5776 4022 04205 6205 .PUSHJ @[BPTCLR] ; clear the breakpoint tables 04206 5775 4023 04207 4527 JMS @ZPUSHJ1 ; (cross field call) 4024 04210 1713 INIPMP ; initialize the IDE disk partition map 4025 04211 6222 CIF 2 4026 04212 5774 JMP @[RDPSS] ; if NVRAM present, possibly overwrite some 4027 ; of these settings with stored ones 4028 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 94 FL Command - Flash download BTS6120.plx 4029 .TITLE FL Command - Flash download 4030 4031 ; 4032 ; Flash command codes for 28Fx00 type EEPROMS 4033 ; 4034 7777 FCMDRA=7777 4035 0220 FCMDRI=0220 4036 0120 FCMDCS=0120 4037 0040 FCMDERA1=0040 4038 0320 FCMDERA2=0320 4039 0100 FCMDPROG=0100 4040 4041 ; Enter here for the FL command... It uses the same download code 4042 ; as DL and RL, but checks for presence of flash and prompts for 4043 ; overwriting it before executing that. 4044 4045 04213 6403 FLLOAD: MM3 ; access flash (if it's there) 4046 04214 6211 CDF 1 4047 4048 ; We want to check that a flash ROM is actually there. This is a bit 4049 ; problematic because the Read ID command returns a manufacturer and 4050 ; device code that are basically arbitrary. However, at least the commands 4051 ; seem to be the same for all flash devices in this class. 4052 ; What we'll do is try switching between array read and ID read mode a 4053 ; couple of times and see if the results are consistent with a flash ROM 4054 ; being there. 4055 4056 04215 1373 TAD [FCMDRA] ; reset flash to array read mode 4057 04216 3772 DCA @[0] 4058 4059 04217 1772 TAD @[0] ; array read mode - hash and stash 4060 04220 7002 BSW 4061 04221 1771 TAD @[2] 4062 04222 3041 DCA LOW 4063 4064 04223 1370 TAD [FCMDRI] ; set flash to read ID mode 4065 04224 3772 DCA @[0] 4066 4067 04225 1772 TAD @[0] ; fetch 1st ID byte 4068 04226 7002 BSW 4069 04227 1771 TAD @[2] ; combine with 2nd ID byte 4070 04230 3040 DCA HIGH 4071 4072 04231 1373 TAD [FCMDRA] ; reset flash to array read mode 4073 04232 3772 DCA @[0] 4074 4075 04233 1772 TAD @[0] ; array read mode - hash and compare 4076 04234 7002 BSW ; with the last result 4077 04235 1771 TAD @[2] 4078 04236 7041 CIA 4079 04237 1041 TAD LOW 4080 04240 7440 SZA 4081 04241 5262 JMP BADFLR ; didn't match! 4082 4083 04242 1370 TAD [FCMDRI] ; set flash to read ID mode 4084 04243 3772 DCA @[0] 4085 4086 04244 1772 TAD @[0] ; fetch 1st ID byte 4087 04245 7002 BSW 4088 04246 1771 TAD @[2] ; combine with 2nd ID byte 4089 4090 04247 6402 MM2 ; back to normal memory access mode 4091 04250 6201 CDF 0 4092 4093 04251 7041 CIA ; compare with last result PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 95 FL Command - Flash download BTS6120.plx 4094 04252 1040 TAD HIGH 4095 04253 7440 SZA 4096 04254 5262 JMP BADFLR ; didn't match! 4097 4098 04255 1041 TAD LOW ; now make sure that we got distinct 4099 04256 7041 CIA ; values from Read Array and Read ID 4100 04257 1040 TAD HIGH 4101 04260 7440 SZA 4102 04261 5265 JMP OKFLR ; different - everything looks okay! 4103 4104 04262 4507 BADFLR: JMS @ZINLMES ; display an error 4105 04263 4343 FLMSG1 4106 04264 5524 JMP @ZRESTA ; and back to prompt 4107 4108 04265 1373 OKFLR: TAD [FCMDRA] ; reset flash to array read mode 4109 04266 3772 DCA @[0] 4110 4111 04267 4507 JMS @ZINLMES ; prompt to make sure we want to do this... 4112 04270 4352 FLMSG2 4113 04271 6205 .PUSHJ @[CONFRM] ; go wait for a "Y" or "y" 04272 5767 4114 04273 7620 SNL CLA ; did they confirm? 4115 04274 5524 JMP @ZRESTA ; no - just abort now 4116 4117 ; and start the download 4118 4119 04275 1366 TAD [ROMWR] ; use the ROM write routine 4120 04276 3765 DCA @[WRPTR] ; ... 4121 04277 1135 TAD ZM256 ; and the record (block) size is 256 4122 04300 3071 DCA RECSIZ ; ... 4123 04301 5764 JMP @[DLOAD1] ; and off we go, no arguments please 4124 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 96 Field 0 Vector Table BTS6120.plx 4125 .TITLE Field 0 Vector Table 4126 4127 4128 ; this is a very small stub that allows us to call functions in Field 0 4129 ; from Field 3. This is accomplished by making .POPJ return via here. 4130 4131 04302 6223 RET0F2: CXF 2 ; return to field 2 4132 04303 6225 .POPJ ; the address is already on the stack 4133 4134 04304 6233 RET0F3: CXF 3 ; return to field 3 4135 04305 6225 .POPJ ; the address is already on the stack 4136 4137 ; variable and functions that we may want to access or hook in this field 4138 ; codes: I=instruction pointer, V=variable, H=hook (CIF n, JMP @.+1, V) 4139 ; Add only to the *end* of this list, please! 4140 ; n.b. JMS linkage functions generally cannot be used here 4141 04306 F0VECTOR: 4142 04306 4304 RET0F3 ; I utility - return to field 0 (must be first) 4143 04307 0000 UPC ; V user program counter (saved by the hardware) 4144 04310 0001 UAC ; V user accumulator 4145 04311 0002 UFLAGS ; V user status (LINK, GT, IF, DF, etc) from GCF 4146 04312 0351 SYSIN9-1 ; H initialization just before monitor entered 4147 04313 7463 CONOUT ; I output a character, no processing 4148 04314 7552 CONIN ; I input a character, no processing, null if none 4149 04315 7400 OUTCHR ; I type a single character 4150 04316 7477 INCHRS ; I input a character, null if none 4151 04317 6322 TOCT4 ; I type an octal number 4152 04320 7104 CRLF ; I type a carriage return/line feed 4153 04321 6102 SPACMP ; I get the next non-blank command character 4154 04322 6104 SPACM0 ; I get a non-blank character starting with the current 4155 04323 6132 BACKUP ; I backup the command line pointer 4156 04324 6115 EOLTST ; I test current character for end of line 4157 04325 6113 EOLNXT ; I test the next character for end of line 4158 04326 0475 GET ; I get the next character from the command line 4159 04327 6720 OCTNW ; I scan an octal number 4160 04330 6441 RANGE ; I scan an address range (e.g. "0-7777") 4161 04331 0377 RESTA-1 ; H monitor restart vector 4162 04332 0453 COMERR ; I report a command syntax error and restart 4163 04333 6277 TDECNW ; I print an unsigned decimal number 4164 04334 2536 NODISK-1 ; H check for disk presence 4165 04335 1262 TYPEIR-1 ; H print the current IR 4166 04336 0007 UIR ; V user IR 4167 04337 0035 ADDR ; V start address returned from RANGE 4168 04340 0036 ADRFLD ; V start field returned from RANGE 4169 04341 0040 HIGH ; V end address returned from RANGE 4170 04342 0042 HGHFLD ; V end field returned from RANGE 4171 04343 7645 BTSTR1-1 ; H CPREQ signaled 4172 04344 0020 PARMAP ; V partition map 4173 04345 0034 RAMBAS ; V base offset - 1 for each RAM disk field 4174 04364 3540 04365 3554 04366 2600 04367 7025 04370 0220 04371 0002 04372 0000 04373 7777 04374 0201 04375 2026 04376 2312 04377 0120 4175 04400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 97 Call Routines in Field 1 BTS6120.plx 4176 .TITLE Call Routines in Field 1 4177 4178 ; This routine will allow a routine in field zero to simulate a .PUSHJ 4179 ; to a routine in field one. Even better, when the routine in field one 4180 ; executes a .POPJ, the return will eventually be to field zero! The 4181 ; contents of the AC are preserved both ways across the call. 4182 ; 4183 ;CALL: 4184 ; JMS @ZPUSHJ1 ; cross field call 4185 ; ; address of a routine in field 1 4186 ; ; with the AC preserved across the call 4187 ; 4188 04400 0000 PUSHJ1: 0 ; call here with a JMS instruction 4189 04401 3217 DCA PUSHAC ; save the caller's AC for a minute 4190 04402 1600 TAD @PUSHJ1 ; then get caller's argument 4191 04403 3216 DCA F1ADDR ; that's the address of the routine to call 4192 04404 1200 TAD PUSHJ1 ; now get caller's return address 4193 04405 7001 IAC ; and skip over the argument 4194 04406 6215 .PUSH ; put that on the stack 4195 04407 7200 CLA ; (PUSH doesn't clear the AC!) 4196 04410 1377 TAD [POPJ1] ; the field one routine will return to 4197 04411 6215 .PUSH ; ... POPJ1: in field one 4198 04412 7200 CLA ; ... 4199 04413 1217 TAD PUSHAC ; restore the original AC contents 4200 04414 6213 CXF 1 ; call with IF = DF = 1 4201 04415 5616 JMP @.+1 ; and go to the code in field 1 4202 04416 F1ADDR: .BLOCK 1 ; gets the address of the field 1 routine 4203 04417 PUSHAC: .BLOCK 1 ; a temporary place to save the AC 4204 4205 ; When the routine in field one executes a .POPJ, it will actually return to 4206 ; the code at POPJ1: _in field one_ !! Since we've also stacked our original 4207 ; caller's return address, the code at POPJ1 really only needs to do two 4208 ; things, a "CXF 0" to return to field zero, and then another .POPJ. 4209 ; Unfortunately, this code has to live in field one, so you won't find it 4210 ; here! 4211 04577 0306 4212 04600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 98 Free Space for Future Expansion! BTS6120.plx 4213 .TITLE Free Space for Future Expansion! 4214 4215 4216 ; space to put patch code for this field 4217 04600 F0PATCH: 4218 4219 05600 .PAGE 30-1 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 99 Front Panel Initialization BTS6120.plx 4220 .TITLE Front Panel Initialization 4221 4222 4223 ; This routine will determine if a FP6120 front panel is attached and, if 4224 ; one is, will initialize it. If a front panel is present, the FPDTCT word 4225 ; will be set to a non-zero value. This serves as a flag to control the 4226 ; actions of all the other front panel code. 4227 05600 7200 FPINIT: CLA ; clear all the FP variables anyway 4228 05601 3057 DCA FNSTAT ; just in case 4229 05602 3060 DCA BTSWCN ; ... 4230 05603 3061 DCA FPPGMM ; ... 4231 4232 ; If a front panel is installed, then the CCPR IOT will not only clear 4233 ; the CP timer and HALTSW flags, but it will also clear the AC as well. 4234 ; If no front panel is present, then CCPR is a no-op. That's an easy 4235 ; way to determine if a FP6120 is present. 4236 05604 7240 STA ; set the AC to -1 4237 05605 6430 CCPR ; clear the AC if an FP is present 4238 05606 7040 CMA ; 0 if no FP, -1 if an FP 4239 05607 3056 DCA FPDTCT ; and set the flag 4240 05610 1056 TAD FPDTCT ; get it back again 4241 05611 7650 SNA CLA ; if there's no front panel 4242 05612 6225 .POPJ ; then we can quit now 4243 4244 ; Just for fun, we display "6120" (in octal, of course) on the ADDRESS 4245 ; LEDs and our BTS6120 version on the DATA LEDs. Unfortunately this works 4246 ; only if the rotary switch is set to MD - you might think it would be easy 4247 ; to make it work for the other positions by adding a WSR here, but it's 4248 ; not that simple. If the rotary switch is set to PS, AC or MQ anything we 4249 ; write there will be overwritten by the UPDISP routine before you ever see 4250 ; it. Sorry. By the way, this rather causually corrupts a word of memory, 4251 ; but this routine is supposed to be used only during initialization anyway... 4252 05613 6266 CPD ; write to main memory 4253 05614 1377 TAD [VERSION] ; get our version number 4254 05615 3776 DCA @[6120] ; and write it to location 6120 4255 05616 6276 SPD ; back to panel data mode 4256 05617 6435 RLOF ; lastly, turn the RUN LED off 4257 05620 6225 .POPJ ; that'll be enough fun for today PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 100 Scan Front Panel Switches BTS6120.plx 4258 .TITLE Scan Front Panel Switches 4259 4260 4261 ; This routine will scan all front panel switches, except for HALT and the 4262 ; rotary switch, and look for work to be done. The HALT switch is ignored 4263 ; until we give a command that will transfer control to main memory (e.g. 4264 ; CONTINUE or BOOT), and the rotary switch is handled by the data display 4265 ; update routine. 4266 ; 4267 ; Note that this routine is called only while we're in panel mode and 4268 ; BTS6120 is active - it's never called by the CP timer. The panel switches 4269 ; (except for HALT and the rotary switch) do nothing while a main memory 4270 ; program is running. 4271 05621 1056 SWSCAN: TAD FPDTCT ; get the front panel flag 4272 05622 7650 SNA CLA ; skip if a panel is attached 4273 05623 6225 .POPJ ; no panel - just quit now 4274 05624 6434 RFNS ; read the state of the function switches 4275 05625 0375 AND [7740] ; isolate the switches we know about 4276 05626 7041 CIA ; has there been any change in switch state 4277 05627 1057 TAD FNSTAT ; ... since we were last here? 4278 05630 6432 SPLK ; ignore everything if PANEL LOCK is on! 4279 05631 7650 SNA CLA ; (switches changed ???) 4280 05632 6225 .POPJ ; no (or PANEL LOCK) - there's nothing to do 4281 4282 ; Now that we've detected a change in the switch state, delay for 4283 ; approximately 10-15 milliseconds to allow the switch to stop bouncing. 4284 ; Remember - this code is used only when we're in panel mode; it's never 4285 ; called by the CP timer, so the delay is inconsequential. 4286 ; 4287 ; Each iteration of the delay loop requires 17 minor cycles, or 4.25us 4288 ; with a 8Mhz clock (6.8us at 5Mhz). A 15 ms delay therefore needs 3529 4289 ; iterations (again, assuming an 8Mhz clock). 4290 05633 1374 TAD [-3529.] ; initialize the timer 4291 05634 7001 SWSCA1: IAC ; [6] increment the AC 4292 05635 7440 SZA ; [7] has it overflowed yet? 4293 05636 5234 JMP SWSCA1 ; [4] nope - keep looping 4294 4295 ; Compute (.NOT. ) .AND. - this function gives a 4296 ; 1 bit for every switch which was not pressed before and is pressed now; 4297 ; those are the ones we want to process! 4298 05637 6434 RFNS ; read the current state 4299 05640 0375 AND [7740] ; mask off the unimportant switches 4300 05641 3301 DCA SWTEMP ; save it for a moment 4301 05642 1057 TAD FNSTAT ; get the old state 4302 05643 7040 CMA ; complement 4303 05644 0301 AND SWTEMP ; not old and new 4304 05645 7421 MQL ; save _that_ too 4305 05646 1301 TAD SWTEMP ; lastly update FNSTAT 4306 05647 3057 DCA FNSTAT ; ... for next time around 4307 05650 7701 ACL ; restore the changed switch map 4308 05651 7450 SNA ; if there are no one bits 4309 05652 6225 .POPJ ; then we've got nothing to do! 4310 4311 ; Now figure out which switch is set. It's not really clear what we should 4312 ; do if more than one switch is depressed at the same time (does a real -8 4313 ; have N key rollover for the front panel?) - in this case we just process 4314 ; the first switch that we detect and ignore the rest. 4315 05653 7004 RAL ; put BOOT in LINK and LA in AC0 4316 05654 7430 SZL ; is BOOT pressed? 4317 05655 5773 JMP @[SWBOOT] ; ... 4318 05656 7421 MQL ; save the bits again 4319 05657 3060 DCA BTSWCN ; clear the BOOT count for any key 4320 05660 7701 ACL ; ... _other_ than BOOT 4321 05661 7510 SPA ; what about LA ? 4322 05662 5302 JMP SWLA ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 101 Scan Front Panel Switches BTS6120.plx 4323 05663 7006 RTL ; get the next two bits 4324 05664 7430 SZL ; next up is LXA 4325 05665 5311 JMP SWLXA ; ... 4326 05666 7510 SPA ; and after that is CLEAR 4327 05667 5772 JMP @[SWCLR] ; ... 4328 05670 7006 RTL ; position the next bits 4329 05671 7430 SZL ; this position is CONTINUE 4330 05672 5771 JMP @[CONT] ; (CONTINUE is exactly C command) 4331 05673 7510 SPA ; and then EXAM 4332 05674 5335 JMP SWEXA ; .... 4333 05675 7004 RAL ; only one left! 4334 05676 7710 SPA CLA ; the last one is DEP 4335 05677 5325 JMP SWDEP ; ... 4336 05700 6225 .POPJ ; it should be impossible to get here! 4337 4338 ; Temporary storage... 4339 05701 0000 SWTEMP: 0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 102 FP LA, LXA, EXAMINE and DEPOSIT Switches BTS6120.plx 4340 .TITLE FP LA, LXA, EXAMINE and DEPOSIT Switches 4341 4342 4343 ; The LOAD ADDRess switch loads the switches (data switches, this time) 4344 ; into the PC and then displays (if the rotary switch is set to MD) the 4345 ; contents of the addressed location. 4346 05702 7604 SWLA: LAS ; read the switch register 4347 05703 3000 DCA UPC ; and deposit that in the PC 4348 05704 6205 .PUSHJ EXMEM ; display that location 05705 5351 4349 05706 6205 .PUSHJ @[TYPEPC] ; type the PC too 05707 5770 4350 05710 5506 JMP @ZCRLF ; finish the line and exit 4351 4352 4353 ; The LOAD EXTenDed ADDRess switch loads SR9..11 into the user's data 4354 ; field and SR7..9 into the user's instruction field. This is similar 4355 ; to loading the flags register, however the upper six bits are unchanged. 4356 05711 7604 SWLXA: LAS ; read the switch register 4357 05712 0367 AND [77] ; keep only the lower six bits 4358 05713 7421 MQL ; save that for a moment 4359 05714 1002 TAD UFLAGS ; get the last user mode flags 4360 05715 0366 AND [7700] ; keep the upper six bits of that 4361 05716 7501 MQA ; put the two together 4362 05717 3002 DCA UFLAGS ; and update the IF/DF 4363 05720 6205 .PUSHJ EXMEM ; display that location 05721 5351 4364 05722 6205 .PUSHJ @[TYPEPS] ; and type it on the console too 05723 5765 4365 05724 5506 JMP @ZCRLF ; finish the line and exit 4366 4367 4368 ; The DEPosit switch writes SR0..11 to the memory location addressed by 4369 ; the PC, increments the PC (but not the IF!) and then displays the contents 4370 ; of the next location. 4371 05725 6205 SWDEP: .PUSHJ @[USERDF] ; change DF to the last user mode IF 05726 5764 4372 05727 6266 CPD ; address main memory 4373 05730 7604 LAS ; read the data switch register 4374 05731 3400 DCA @UPC ; deposit them into memory 4375 05732 2000 ISZ UPC ; increment the memory address 4376 05733 7000 NOP ; ... 4377 05734 5341 JMP SWEXA1 ; and fall into the EXMEM routine 4378 4379 4380 ; The EXAMine switch increments the PC and then displays the memory location 4381 ; addressed by {IR,PC}. Note that the EXAM switch always does the same thing, 4382 ; however the data display only shows the memory data if the rotary switch is 4383 ; set to MD! 4384 05735 2000 SWEXA: ISZ UPC ; no - increment the user PC 4385 05736 7000 NOP ; ignore any wrap around 4386 05737 6205 .PUSHJ EXMEM ; display that location on the lights 05740 5351 4387 05741 1000 SWEXA1: TAD UPC ; fix up the PC and IF 4388 05742 3035 DCA ADDR ; ... for TMEM 4389 05743 1002 TAD UFLAGS ; ... 4390 05744 0131 AND ZK70 ; ... 4391 05745 3036 DCA ADRFLD ; ... 4392 05746 6205 .PUSHJ @[TMEM] ; type it on the console too 05747 5763 4393 05750 5506 JMP @ZCRLF ; ... 4394 4395 4396 ; This routine displays the location addressed by {IF,PC}. It's used 4397 ; by all the examine, load address and deposit routines... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 103 FP LA, LXA, EXAMINE and DEPOSIT Switches BTS6120.plx 4398 05751 6205 EXMEM: .PUSHJ @[USERDF] ; change DF to the last user mode IF 05752 5764 4399 05753 6266 CPD ; address main memory next 4400 05754 1400 TAD @UPC ; and read the location at {IF,PC} 4401 05755 7200 CLA ; we don't actually care what we read! 4402 05756 6276 SPD ; back to panel memory 4403 05757 6201 CDF 0 ; ... 4404 05760 6225 .POPJ ; and we're done... 4405 05763 1060 05764 6000 05765 1265 05766 7700 05767 0077 05770 1255 05771 2216 05772 6017 05773 6007 05774 1067 05775 7740 05776 6120 05777 0271 4406 06000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 104 Change Current DF to User's IF BTS6120.plx 4407 .TITLE Change Current DF to User's IF 4408 4409 4410 ; This routine will change the current data field to the user's instruction 4411 ; field, as determined by the last user mode PS in UFLAGS... 4412 06000 7200 USERDF: CLA ; just in case! 4413 06001 1002 TAD UFLAGS ; get the last user mode flags 4414 06002 0131 AND ZK70 ; isolate just the instruction field 4415 06003 1377 TAD [CDF 0] ; make a CDF instruction out of it 4416 06004 3205 DCA .+1 ; and execute that 4417 06005 7000 NOP ; (gets overwritten with a CDF instruction) 4418 06006 6225 .POPJ ; return and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 105 START, CONTINUE and BOOT Switches BTS6120.plx 4419 .TITLE START, CONTINUE and BOOT Switches 4420 4421 4422 ; The BOOT switch (what else?) boots the PDP-8. Because BOOT is a fairly 4423 ; dangerous function, we steal a cue from the PDP-8/A and require it to be 4424 ; pressed _twice_ in succession before anything happens. The flag BTSWCN 4425 ; (BooT SWitch CouNt) keeps track of the number of times BOOT has been 4426 ; pressed. 4427 ; 4428 ; Note that the BOOT switch ignores the state of the RUN/HALT switch (i.e. 4429 ; it doesn't single step if the HALT switch is down). That seems like the 4430 ; most useful behavior. 4431 06007 2060 SWBOOT: ISZ BTSWCN ; have we been here before (recently)? 4432 06010 5214 JMP SWBOO1 ; no - wait for a second toggle 4433 06011 6205 .PUSHJ @ZCRLF ; ... 06012 5506 4434 06013 5776 JMP @[BOOT1] ; yes - go find something to boot! 4435 4436 ; Here for the first toggle of two... 4437 06014 7240 SWBOO1: STA ; set the AC to -1 4438 06015 3060 DCA BTSWCN ; and set the counter for next time 4439 06016 6225 .POPJ ; do nothing else this time 4440 4441 4442 ; The CLEAR key clears the AC and other processor registers and then 4443 ; asserts IOCLR L. It also clears the flag bits in the PS, but it leaves 4444 ; the IF, DF and PC alone. It does _not_ (contrary to what I once thought) 4445 ; actually start execution! 4446 06017 3004 SWCLR: DCA USP1 ; clear both stack pointers 4447 06020 3005 DCA USP2 ; ... 4448 06021 3003 DCA UMQ ; the multiplier quotient 4449 06022 3001 DCA UAC ; and the AC 4450 06023 1002 TAD UFLAGS ; get the current flags 4451 06024 0375 AND [77] ; clear all but the IF and DF 4452 06025 3002 DCA UFLAGS ; ... 4453 06026 3061 DCA FPPGMM ; clear the front panel program mode 4454 06027 6007 CAF ; finally, assert IOCLR L 4455 06030 6225 .POPJ ; all done! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 106 HALT Switch BTS6120.plx 4456 .TITLE HALT Switch 4457 4458 4459 ; This routine will test the state of the front panel HALT switch and 4460 ; take the skip return if it is in the RUN (i.e. UP) position. If the 4461 ; switch is in the HALT (DOWN) position, then commands that would normally 4462 ; start a main memory program (e.g. STart, Continue, etc) single step 4463 ; instead. 4464 ; 4465 ; If no front panel is installed, this routine always takes the skip 4466 ; (i.e. RUN) return! 4467 ; 4468 ; NOTE that this routine must be called with a JMS and not the usual 4469 ; PUSHJ/POPJ combination! 4470 06031 0000 CHKHLT: 0 ; call here with a JMS! 4471 06032 7300 CLA CLL ; just in case 4472 06033 1056 TAD FPDTCT ; any front panel installed? 4473 06034 7650 SNA CLA ; skip if a FP6120 is present 4474 06035 5242 JMP CHKHL1 ; nope - take the skip return now 4475 06036 6434 RFNS ; read the function switches 4476 06037 0374 AND [20] ; isolate the halt switch bit 4477 06040 6432 SPLK ; ignore it if PANEL LOCK is on! 4478 06041 7640 SZA CLA ; HALT is 1 for UP, 0 for DOWN 4479 06042 2231 CHKHL1: ISZ CHKHLT ; switch is UP, take the skip return 4480 06043 5631 JMP @CHKHLT ; and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 107 Update the Front Panel Data Display BTS6120.plx 4481 .TITLE Update the Front Panel Data Display 4482 4483 4484 ; This routine will read the rotary switch position and display the 4485 ; selected data on the data LEDs. There are a couple of points to 4486 ; keep in mind while you read this: 4487 ; 4488 ; * The display is selected by the 4 least significant bits returned 4489 ; by the RFNS IOT. Exactly _one_ of these bits will be a one! 4490 ; 4491 ; * The MD DISP position is handled by the hardware and requires no 4492 ; action on our part. Actually the CP timer interrupt is disabled 4493 ; when the switch is in the MD DISP position, but that doesn't 4494 ; guarantee that this routine won't be called from somewhere else. 4495 ; 4496 ; * If the FPPGMM (Front Panel Program Mode) flag is non-zero, then the 4497 ; main memory program is controlling the data display and, rather than 4498 ; displaying any of the registers, we display the contents of FPPGMD. 4499 ; Of course, this works only if the rotary switch is NOT set to MD! 4500 ; 4501 ; * Since this routine is also called by the 30Hz timer, we want it 4502 ; to be as fast as possible! 4503 ; 4504 06044 1056 UPDISP: TAD FPDTCT ; get the front panel flag 4505 06045 7650 SNA CLA ; is a front panel attached? 4506 06046 6225 .POPJ ; nope - just quit now 4507 06047 1061 TAD FPPGMM ; front panel program mode? 4508 06050 7640 SZA CLA ; skip if not 4509 06051 5300 JMP PGMDSP ; yes - display the program data only 4510 06052 6434 RFNS ; read the rotary switch 4511 06053 7010 RAR ; put PS DISP L in the link 4512 06054 7430 SZL ; is it set? 4513 06055 5265 JMP PSDISP ; yes - go display the flags 4514 06056 7010 RAR ; next up is AC DISP 4515 06057 7430 SZL ; ??? 4516 06060 5272 JMP ACDISP ; ... 4517 06061 7010 RAR ; test MQ DISP next 4518 06062 7430 SZL ; ??? 4519 06063 5275 JMP MQDISP ; that's the one - go show the MQ 4520 ; The last bit is MD DISP L which, unless the FP hardware is 4521 ; broken, _MUST_ be set. There's no point in checking - just do it. 4522 ; It gets even better because the memory display is handled by the 4523 ; hardware, so there's nothing we need to do! 4524 06064 5270 JMP UPDIS2 ; no action required 4525 4526 ; Here to display the processor flags... 4527 06065 7200 PSDISP: CLA ; ... 4528 06066 1002 TAD UFLAGS ; get the user mode flags 4529 06067 6246 UPDIS1: WSR ; display then on the lights 4530 06070 7300 UPDIS2: CLA CLL ; (just in case!) 4531 06071 6225 .POPJ ; and we're outta here 4532 4533 ; Here to display the AC on the lights... 4534 06072 7200 ACDISP: CLA ; ... 4535 06073 1001 TAD UAC ; display the last user mode AC 4536 06074 5267 JMP UPDIS1 ; ... 4537 4538 ; And here to display the MQ... 4539 06075 7200 MQDISP: CLA ; ... 4540 06076 1003 TAD UMQ ; display the last user mode MQ 4541 06077 5267 JMP UPDIS1 ; ... 4542 4543 ; Here to display the program data.. 4544 06100 1062 PGMDSP: TAD FPPGMD ; get the program data 4545 06101 5267 JMP UPDIS1 ; display it and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 108 Simple Lexical Functions BTS6120.plx 4546 .TITLE Simple Lexical Functions 4547 4548 4549 ; This routine will skip over any spaces in the command line and return the 4550 ; next non-space character in the AC and SAVCHR... 4551 4552 ; Here to start skipping with the next character... 4553 06102 6205 SPACMP: .PUSHJ @ZGET ; Get the next character 06103 5515 4554 4555 ; Here to consider the current character and then skip... 4556 06104 7200 SPACM0: CLA ; Be sure the AC is safe to use 4557 06105 1050 TAD SAVCHR ; And look at the current character 4558 06106 1133 TAD ZMSPACE ; Compare it to a space 4559 06107 7650 SNA CLA ; ??? 4560 06110 5302 JMP SPACMP ; Keep going until we don't find one 4561 06111 1050 TAD SAVCHR ; Restore the character 4562 06112 6225 .POPJ ; And we're all done 4563 4564 ; This routine will examine the current character (in SAVCHR) or the next 4565 ; character (via GET) for end of line, which is stored as a null byte). If 4566 ; it isn't the EOL, then COMERR is called and the current command is aborted, 4567 ; otherwise this routine just returns... 4568 4569 ; Enter here to examine the next character... 4570 06113 6205 EOLNXT: .PUSHJ @ZGET ; Load the next character 06114 5515 4571 ; Then fall into the current character test 4572 4573 ; Enter here to examine the current character... 4574 06115 6205 EOLTST: .PUSHJ @ZSPACM0 ; Allow blanks at the end of the line 06116 5511 4575 06117 7640 SZA CLA ; Is it the end of the line ?? 4576 06120 5525 JMP @ZCOMERR ; No -- that's bad 4577 06121 6225 .POPJ ; Yes -- that's good 4578 4579 ; This routine will test either the current character (via SAVCHR) or the 4580 ; next character (via GET) to see if it's a space. If it isn't, then it 4581 ; jumps to COMERR and aborts the current command... 4582 4583 ; Enter here to examine the next character... 4584 06122 6205 SPANXT: .PUSHJ @ZGET ; get the next character 06123 5515 4585 ; and fall into SPATST... 4586 4587 ; Enter here to examine the current character 4588 06124 7200 SPATST: CLA ; don't require that the AC be cleared 4589 06125 1050 TAD SAVCHR ; get the current character 4590 06126 1133 TAD ZMSPACE ; and compare it to a space 4591 06127 7640 SZA CLA ; well?? 4592 06130 5525 JMP @ZCOMERR ; not equal - this is a bad command line 4593 06131 6225 .POPJ ; it's a space 4594 4595 4596 ; This routine will backup the command scanner so that the character 4597 ; just read will be read again with the next call to GET... 4598 06132 7240 BACKUP: STA ; Load the AC with -1 4599 06133 1013 TAD L ; Then decrement the line pointer 4600 06134 3013 DCA L ; ... 4601 06135 6225 .POPJ ; That's all it takes 4602 06174 0020 06175 0077 06176 2452 06177 6201 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 109 Simple Lexical Functions BTS6120.plx 4603 06200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 110 Type ASCII Strings BTS6120.plx 4604 .TITLE Type ASCII Strings 4605 4606 4607 ; This routine will type a ASCIZ string stored in field 1 using the standard 4608 ; OS/8 "3 for 2" packing system. This format is used by the monitor to store 4609 ; help and error messages. On call, the address of the string is passed in the 4610 ; AC and, on return, the AC will always be cleared. 4611 06200 1377 OUTSTR: TAD [-1] ; auto index registers pre-increment 4612 06201 3010 DCA X1 ; ... 4613 06202 7346 NLM3 ; load the AC with -3 4614 06203 3070 DCA DIGITS ; and initialize the character counter 4615 4616 ; Get the next character and output it... 4617 06204 6211 OUTST1: CDF 1 ; strings always live in field 1 4618 06205 2070 ISZ DIGITS ; which character are we on? 4619 06206 5227 JMP OUTST2 ; first or second - they're easy 4620 4621 ; Extract the third character from a triplet... 4622 06207 7346 NLM3 ; re-initialize the character counter 4623 06210 3070 DCA DIGITS ; ... 4624 06211 7344 NLM2 ; then load the AC with -2 4625 06212 1010 TAD X1 ; and backup the string pointer 4626 06213 3010 DCA X1 ; ... 4627 06214 1410 TAD @X1 ; get the first word of the pair 4628 06215 0135 AND ZK7400 ; get the upper four bits of the word 4629 06216 7002 BSW ; position them in the upper bits of the byte 4630 06217 7106 CLL RTL ; ... 4631 06220 7421 MQL ; save it in the MQ for a while 4632 06221 1410 TAD @X1 ; then get the second word again 4633 06222 0135 AND ZK7400 ; the upper four bits again 4634 06223 7002 BSW ; become the lower for bits of the byte 4635 06224 7112 CLL RTR ; ... 4636 06225 7501 MQA ; put the byte together 4637 06226 5230 JMP OUTST3 ; and type it normally 4638 4639 ; Here for the first or second character of a triplet... 4640 06227 1410 OUTST2: TAD @X1 ; get the character 4641 06230 0130 OUTST3: AND ZK177 ; trim it to just seven bits 4642 06231 6201 CDF 0 ; restore the original data field 4643 06232 7450 SNA ; end of string ? 4644 06233 6225 .POPJ ; yes - we can quit now 4645 06234 6205 .PUSHJ @ZOUTCHR ; nope - type this one too 06235 5474 4646 06236 5204 JMP OUTST1 ; and go do the next 4647 4648 ; This routine does exactly the same thing as OUTSTR, except that it allows 4649 ; the message pointer to be passed in line, via a JMS instruction 4650 06237 0000 INLMES: 0 ; call here via a JMS instruction 4651 06240 7200 CLA ; ... 4652 06241 1637 TAD @INLMES ; fetch the string address 4653 06242 6205 .PUSHJ OUTSTR ; type it out 06243 5200 4654 06244 2237 ISZ INLMES ; skip over the address 4655 06245 5637 JMP @INLMES ; and return 4656 4657 ; This routine will type an ASCIZ string, packed one character per word and 4658 ; terminated with a null character, on the terminal. The address of the 4659 ; string, -1, should be loaded into the AC before calling this routine, and 4660 ; the AC will always be cleared on return. 4661 06246 3010 TASCIZ: DCA X1 ; save the pointer to the string 4662 06247 1410 TASCI1: TAD @X1 ; and get the first character 4663 06250 7450 SNA ; is this the end of the string ?? 4664 06251 6225 .POPJ ; yes -- quit now 4665 06252 6205 .PUSHJ @ZOUTCHR ; no -- type this character 06253 5474 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 111 Type ASCII Strings BTS6120.plx 4666 06254 5247 JMP TASCI1 ; and then loop until the end 4667 4668 ; This routine is identical to TASCIZ, except that the string is stored in 4669 ; field 1, rather than field 0... 4670 06255 3010 TASZF1: DCA X1 ; save the pointer to the string 4671 06256 6211 CDF 1 ; the string is in field 1 4672 06257 1410 TAD @X1 ; and get the next character 4673 06260 6201 CDF 0 ; back to our field 4674 06261 7450 SNA ; is this the end of the string ?? 4675 06262 6225 .POPJ ; yes -- quit now 4676 06263 6205 .PUSHJ @ZOUTCHR ; no -- type this character 06264 5474 4677 06265 5256 JMP TASZF1+1 ; and then loop until the end PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 112 Type SIXBIT Words, and Characters BTS6120.plx 4678 .TITLE Type SIXBIT Words, and Characters 4679 4680 4681 ; This routine will type the two character SIXBIT word contained in the AC. 4682 ; It always types exactly two characters, so if the second character is a null 4683 ; (00), then a trailing blank appears. The AC is cleared on return. 4684 06266 3065 TSIXW: DCA WORD ; Save the 2 characters 4685 06267 1065 TAD WORD ; And get them back 4686 06270 7002 BSW ; Position the first one 4687 06271 6205 .PUSHJ TSIXC ; And type it out 06272 5274 4688 06273 1065 TAD WORD ; No -- get the second character 4689 ; And fall into the TSIXC routine 4690 4691 ; This routine will type a single SIXBIT character from the right 4692 ; byte of the AC. The AC will be cleared on return. 4693 06274 0376 TSIXC: AND [77] ; Trim the character to just 6 bits 4694 06275 1375 TAD [" "] ; No -- convert the character to ASCII 4695 06276 5774 JMP @[THCHAR] ; And type it out PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 113 Type Decimal Numbers BTS6120.plx 4696 .TITLE Type Decimal Numbers 4697 4698 4699 ; This routine will type the contents of the AC in decimal. It always 4700 ; treats the AC as an unsigned quantity and will type numbers from 0 to 4095. 4701 ; It uses locations WORD and COUNT and the AC is always cleared on return. 4702 06277 3065 TDECNW: DCA WORD ; remember the number to be typed 4703 06300 3070 DCA DIGITS ; and clear the quotient 4704 06301 1065 TAD WORD ; get the dividend back again 4705 4706 ; Divide by 10 via repeated subtraction... 4707 06302 7100 TDECN1: CLL ; make sure the LINK is clear 4708 06303 1373 TAD [-10.] ; subtract 10 from the dividend 4709 06304 7420 SNL ; did it fit ??? 4710 06305 5310 JMP TDECN2 ; no -- go get the remainder 4711 06306 2070 ISZ DIGITS ; yes -- increment the quotient 4712 06307 5302 JMP TDECN1 ; and keep dividing 4713 4714 ; Now figure the remainder... 4715 06310 1372 TDECN2: TAD [10.] ; correct the remainder 4716 06311 6215 .PUSH ; and save it on the stack 4717 06312 7200 CLA ; get the quotient 4718 06313 1070 TAD DIGITS ; ... 4719 06314 7450 SNA ; is it zero ??? 4720 06315 5320 JMP TDECN3 ; yes -- proceed 4721 06316 6205 .PUSHJ TDECNW ; no type that part first 06317 5277 4722 4723 ; Here to type the digit and return... 4724 06320 6235 TDECN3: .POP ; restore the remainder 4725 06321 5771 JMP @[TDIGIT] ; type it in ASCII and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 114 Type Octal Numbers BTS6120.plx 4726 .TITLE Type Octal Numbers 4727 4728 4729 ; This routine will type a 4 digit octal number passed in the AC. It always 4730 ; prints exactly four digits, with leading zeros added as necessary. The AC 4731 ; will be cleared on return. 4732 06322 3065 TOCT4: DCA WORD ; save the number to type 4733 06323 1370 TAD [-4] ; and get the number of iterations 4734 06324 3070 TOCTN: DCA DIGITS ; ... 4735 4736 ; Extract one digit and print it... 4737 06325 1065 TOCTL: TAD WORD ; get the remaining bits 4738 06326 7106 CLL RTL ; shift them left 2 bits 4739 06327 7006 RTL ; and then 2 more (remember the link!) 4740 06330 3050 DCA SAVCHR ; remember that for a later 4741 06331 1050 TAD SAVCHR ; and we also need it now 4742 06332 7010 RAR ; restore the extra bit (in the link) 4743 06333 3065 DCA WORD ; then remember the remaining bits 4744 06334 1050 TAD SAVCHR ; get the digit back 4745 06335 0132 AND ZK7 ; trim it to just 3 bits 4746 06336 6205 .PUSHJ @[TDIGIT] ; type it out 06337 5771 4747 4748 ; Here after we have typed another digit... 4749 06340 2070 ISZ DIGITS ; is this enough ?? 4750 06341 5325 JMP TOCTL ; no -- keep typing 4751 06342 6225 .POPJ ; yes -- quit now 4752 4753 ; This routine is identical to TOCT4, except that it types only three digits 4754 ; with leading zeros. It's useful for printing eight bit quantities... 4755 06343 7014 TOCT3: R3L ; throw away the most significant digit 4756 06344 3065 DCA WORD ; save the value to be typed 4757 06345 7346 NLM3 ; get the number of iterations 4758 06346 5324 JMP TOCTN ; and join the regular code 4759 4760 ; This small routine will type an octal number in the AC followed by a space. 4761 06347 6205 TOCT4S: .PUSHJ TOCT4 ; then type the data in octal 06350 5322 4762 06351 5475 JMP @ZTSPACE ; finally type a space and return 4763 4764 ; This small routine will type an octal number from the AC followed by a CRLF. 4765 06352 6205 TOCT4C: .PUSHJ TOCT4 ; and type that in octal 06353 5322 4766 06354 5506 JMP @ZCRLF ; finish with a CRLF 4767 4768 06355 6205 TOCT4M: .PUSHJ TOCT4 ; and type that in octal 06356 5322 4769 06357 6205 .PUSHJ @ZCRLF ; finish with a CRLF 06360 5506 4770 06361 5524 JMP @ZRESTA 4771 06370 7774 06371 7102 06372 0012 06373 7766 06374 7427 06375 0040 06376 0077 06377 7777 4772 06400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 115 Type 15 Bit Addresses BTS6120.plx 4773 .TITLE Type 15 Bit Addresses 4774 4775 4776 ; This routine will type a 15 bit address, passed in location ADDR, and with 4777 ; the field is in location ADRFLD. The address will be typed as a 5 digit 4778 ; octal number, and then followed by a "/" character and a space. The initial 4779 ; contents of the AC are ignored and the AC is always cleared on return. 4780 06400 7200 TADDR: CLA ; ... 4781 06401 1036 TAD ADRFLD ; get the high 3 bits of the address 4782 06402 6205 .PUSHJ @[TFIELD] ; type that out 06403 5777 4783 06404 1035 TAD ADDR ; then get the address 4784 06405 6205 .PUSHJ @ZTOCT4 ; and type all 12 bits of that 06406 5477 4785 06407 6205 .PUSHJ @[TSLASH] ; type a slash as a separator 06410 5776 4786 06411 5475 JMP @ZTSPACE ; finish with a space 4787 4788 ; This routine will type a single octal digit which represents a memory 4789 ; field. The field should be passed in the AC. 4790 06412 7010 TFIELD: RAR ; right justify the field number 4791 06413 7012 RTR ; ... 4792 06414 0132 AND ZK7 ; trim it to just 3 bits 4793 06415 5775 JMP @[TDIGIT] ; and fall into TDIGIT... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 116 Scan Addresses BTS6120.plx 4794 .TITLE Scan Addresses 4795 4796 4797 ; This routine will read a 15 bit address into registers ADDR and ADRFLD. 4798 06416 6205 RDADDR: .PUSHJ @[OCTNF] ; read the 15 bit address 06417 5774 4799 06420 1065 TAD WORD ; get the low order bits 4800 06421 3035 DCA ADDR ; and put them in ADDR 4801 06422 6225 .POPJ ; that's it... 4802 4803 ; This routine will read a 15 bit address into registers HIGH and HGHFLD. 4804 06423 6205 RDHIGH: .PUSHJ RDADDR ; read a 15 bit address 06424 5216 4805 06425 1035 TAD ADDR ; get the low order bits 4806 06426 3040 DCA HIGH ; into HIGH 4807 06427 1036 TAD ADRFLD ; get the field 4808 06430 3042 DCA HGHFLD ; into HGHFLD 4809 06431 6225 .POPJ ; and that's all 4810 4811 ; This routine will read a 15 bit address into registers LOW AND LOWFLD. 4812 06432 6205 RDLOW: .PUSHJ RDADDR ; the same thing as before 06433 5216 4813 06434 1035 TAD ADDR ; ... 4814 06435 3041 DCA LOW ; only the names have changed 4815 06436 1036 TAD ADRFLD ; ... 4816 06437 3043 DCA LOWFLD ; ... 4817 06440 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 117 Scan an Address Range BTS6120.plx 4818 .TITLE Scan an Address Range 4819 4820 4821 ; This routine will read either one or two octal numbers which describe a 4822 ; range of memory addresses. A range may be a single number (in which case 4823 ; the starting and ending values are the same) or two numbers with a space 4824 ; character between them (in which case the first number is the starting value 4825 ; and the last is the ending value). The starting value is always returned in 4826 ; locations LOW/LOWFLD and ADDR/ADRFLD, and the ending value is placed in 4827 ; HIGH/HGHFLD. If two addresses were seen, the LINK will be set upon return; 4828 ; it is cleared if only one address was found. 4829 06441 6205 RANGE: .PUSHJ RDLOW ; first read the low part of the range 06442 5232 4830 06443 6205 .PUSHJ @ZSPACM0 ; get the next non-space character 06444 5511 4831 06445 1373 TAD [-"-"] ; is it a range delimiter ?? 4832 06446 7640 SZA CLA ; ??? 4833 06447 5265 JMP RANGE1 ; no -- this must be the single address type 4834 4835 ; Here for a two address range... 4836 06450 6205 .PUSHJ RDHIGH ; go read the high order part of the range 06451 5223 4837 06452 1041 TAD LOW ; make ADDR point to the starting point 4838 06453 3035 DCA ADDR ; ... 4839 06454 1043 TAD LOWFLD ; ... 4840 06455 3036 DCA ADRFLD ; ... 4841 06456 6205 .PUSHJ TSTADR ; then be sure the numbers are in order 06457 5306 4842 06460 7020 CML ; ... 4843 06461 7630 SZL CLA ; ??? 4844 06462 6225 .POPJ ; yes -- return with the link set 4845 06463 4526 JMS @ZERROR ; no -- this isn't legal 4846 06464 3453 ERRRAN ; ?WRONG ORDER 4847 4848 ; Here for a single address range... 4849 06465 1041 RANGE1: TAD LOW ; set the high equal to the low 4850 06466 3040 DCA HIGH ; ... 4851 06467 1043 TAD LOWFLD ; ... 4852 06470 3042 DCA HGHFLD ; ... 4853 06471 7100 CLL ; Then return with the link cleared 4854 06472 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 118 Address Arithmetic BTS6120.plx 4855 .TITLE Address Arithmetic 4856 4857 4858 ; This routine will increment the 15 bit address contained in registers 4859 ; ADDR and ADRFLD. If the address increments past 77777, the link will be 4860 ; 1 on return; otherwise it is always 0. 4861 06473 7300 NXTADR: CLA CLL ; ... 4862 06474 2035 ISZ ADDR ; increment the address 4863 06475 6225 .POPJ ; no wrap around -- leave the field alone 4864 06476 1036 TAD ADRFLD ; wrap around -- increment the field too 4865 06477 1372 TAD [-70] ; are we already in field 7 ?? 4866 06500 7510 SPA ; ??? 4867 06501 7020 CML ; no -- make the LINK be cleared on return 4868 06502 1371 TAD [70+10] ; restore and increment the field 4869 06503 0131 AND ZK70 ; only allow these bits in the result 4870 06504 3036 DCA ADRFLD ; and put it back 4871 06505 6225 .POPJ ; ... 4872 4873 ; This routine will compare the 15 bit address in registers ADDR and 4874 ; ADRFLD to the address in registers HIGH and HGHFLD. If ADDR/ADRFLD 4875 ; is less than HIGH/HGHFLD, the link will be zero on return. If ADDR/ADRFLD 4876 ; is greater then or equal to HIGH/HGHFLD, the link will be one. 4877 06506 7300 TSTADR: CLA CLL ; clear the AC and set L = 0 4878 06507 1036 TAD ADRFLD ; get the field 4879 06510 7061 CMA IAC CML ; negate the field and set L = 1 4880 06511 1042 TAD HGHFLD ; compare to the high field 4881 06512 7640 SZA CLA ; are they equal ?? 4882 06513 6225 .POPJ ; no -- the LINK has the correct status 4883 06514 1040 TAD HIGH ; yes -- compare the addresses 4884 06515 7041 CMA CIA ; L = 0 now 4885 06516 1035 TAD ADDR ; ... 4886 06517 7200 CLA ; clear the AC 4887 06520 6225 .POPJ ; but return the status in the LINK 4888 4889 ; This routine will swap the 15 bit address in ADDR/ADRFLD with the the 4890 ; 15 bit address in LOW/LOWFLD. The AC is always cleared. 4891 06521 7200 SWPADR: CLA ; ... 4892 06522 1041 TAD LOW ; get one value 4893 06523 7421 MQL ; and save it in the MQ 4894 06524 1035 TAD ADDR ; then get the other 4895 06525 3041 DCA LOW ; move it to the other place 4896 06526 7501 MQA ; and get the original one back 4897 06527 3035 DCA ADDR ; it goes in the second location 4898 06530 1043 TAD LOWFLD ; now do the same thing for fields 4899 06531 7421 MQL ; ... 4900 06532 1036 TAD ADRFLD ; ... 4901 06533 3043 DCA LOWFLD ; ... 4902 06534 7501 MQA ; ... 4903 06535 3036 DCA ADRFLD ; ... 4904 06536 6225 .POPJ ; that's all there is to it 4905 06571 0100 06572 7710 06573 7723 06574 7004 06575 7102 06576 7074 06577 6412 4906 06600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 119 Scan a Command Name BTS6120.plx 4907 .TITLE Scan a Command Name 4908 4909 4910 ; This routine will scan a command or register name for the monitor. Names 4911 ; are always alphabetic, may not contain any digits, and are limited to one or 4912 ; two letters. The result is stored, in SIXBIT, in location NAME. One letter 4913 ; commands are left justified and padded on the right with zeros. If the end 4914 ; of line is the next character, then this routine will return with NAME set 4915 ; to zero and no error. If, however, there is a least one character out there 4916 ; and it is not a letter, then COMERR will be called... 4917 06600 7200 NAMENW: CLA ; be sure the AC is zero 4918 06601 3045 DCA NAME ; and clear the resulting name 4919 06602 6205 .PUSHJ @ZSPACMP ; get the next character, whatever it is 06603 5510 4920 06604 7450 SNA ; is there anything there ?? 4921 06605 6225 .POPJ ; no -- just give up now 4922 06606 6205 .PUSHJ ALPHA ; see if it is a letter 06607 5227 4923 06610 7420 SNL ; was it a letter ?? 4924 06611 5525 JMP @ZCOMERR ; no -- this isn't legal 4925 06612 1133 TAD ZMSPACE ; yes -- convert it to SIXBIT 4926 06613 7002 BSW ; left justify it 4927 06614 3045 DCA NAME ; and store it in word 4928 4929 ; Check for a second letter in the name... 4930 06615 6205 .PUSHJ @ZGET ; get the next character 06616 5515 4931 06617 6205 .PUSHJ ALPHA ; is this a letter ?? 06620 5227 4932 06621 7420 SNL ; ??? 4933 06622 5512 JMP @ZBACKUP ; no -- put it back and return 4934 06623 1133 TAD ZMSPACE ; yes -- convert it to SIXBIT too 4935 06624 1045 TAD NAME ; put both letters together 4936 06625 3045 DCA NAME ; ... 4937 06626 6225 .POPJ ; then that's all 4938 4939 ; This routine will return with the LINK bit set if the AC holds a letter, 4940 ; and with the LINK reset if it does not. In either case the AC is not 4941 ; disturbed... 4942 06627 7120 ALPHA: STL ; be sure the link starts in a known state 4943 06630 1377 TAD [-"A"] ; compare it to the first letter 4944 06631 7500 SMA ; skip if it isn't a letter 4945 06632 5235 JMP ALPHA1 ; it might be -- look further 4946 06633 1376 TAD ["A"] ; it's not a letter -- restore the AC 4947 06634 6225 .POPJ ; and quit (the link is zero now !!) 4948 4949 ; Here if it might be a letter (the link is also zero now)... 4950 06635 1375 ALPHA1: TAD ["A"-"Z"-1] ; now compare it to the other end 4951 06636 7500 SMA ; skip if it is a letter 4952 06637 7020 CML ; it isn't a letter -- set the link to a 0 4953 06640 1374 TAD ["Z"+1] ; restore the character and the link 4954 06641 6225 .POPJ ; then that's all PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 120 Command Lookup and Dispatch BTS6120.plx 4955 .TITLE Command Lookup and Dispatch 4956 4957 4958 ; This routine will lookup a command or register name in a table and then 4959 ; dispatch to the corresponding routine. The address of the table, should 4960 ; be passed in the AC. The table is formatted as two word entries - the first 4961 ; word of a pair is the SIXBIT name of the command or register, and the second 4962 ; word is the address of the routine to call. As soon as this routine finds a 4963 ; first word that matches the value currently in NAME, it will jump to the 4964 ; routine indicated by the second word. The table ends with a zero word 4965 ; followed by the address of an error routine - the zero word always matches 4966 ; the current name and the error routine will be called. 4967 ; 4968 ; NOTE: Command tables are always stored in field one, however the addresses 4969 ; of all the routines they reference are always in field zero! 4970 ; 4971 ; NOTE: Auto index registers pre-decrement, so the address -1 of the table 4972 ; must be passed in the AC! 4973 06642 3010 MATCH: DCA X1 ; save the pointer to the table 4974 06643 6211 CDF 1 ; command tables are stored in field 1 4975 4976 ; Search for a name which matches... 4977 06644 1410 MATCH1: TAD @X1 ; pick up the name (from field 1) 4978 06645 7450 SNA ; is this the end of the table ?? 4979 06646 5255 JMP MATCH2 ; yes -- this always matches 4980 06647 7041 CIA ; make the word negative 4981 06650 1045 TAD NAME ; and compare it to the desired value 4982 06651 7650 SNA CLA ; ??? 4983 06652 5255 JMP MATCH2 ; a match !! 4984 06653 2010 ISZ X1 ; no match -- skip over the address 4985 06654 5244 JMP MATCH1 ; and keep looking 4986 4987 ; Here when we find a match... 4988 06655 1410 MATCH2: TAD @X1 ; get the address of the routine 4989 06656 3261 DCA MATCH3 ; put that in a safe place 4990 06657 6201 CDF 0 ; change back to the usual data field 4991 06660 5661 JMP @MATCH3 ; then branch to the right routine 4992 4993 ; Temporary storage for MATCH... 4994 06661 MATCH3: .BLOCK 1 ; address of the matching routine PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 121 Scan Decimal Numbers BTS6120.plx 4995 .TITLE Scan Decimal Numbers 4996 4997 4998 ; This routine will read a decimal number from the command line and return 4999 ; its value in location WORD. The value is limited to 12 bits and overflows 5000 ; are not detected. At least one decimal digit must be found on the command 5001 ; line or COMERR will be called, and the first non-digit character found will 5002 ; be returned in location SAVCHR. 5003 06662 7200 DECNW: CLA ; ignore the AC initially 5004 06663 3065 DCA WORD ; clear the total 5005 06664 3070 DCA DIGITS ; and the digit counter 5006 06665 6205 .PUSHJ @ZSPACMP ; ignore any leading blanks 06666 5510 5007 5008 ; Check for a decimal digit... 5009 06667 1373 DECNW1: TAD [-"0"] ; compare it to zero 5010 06670 7510 SPA ; ??? 5011 06671 5313 JMP DECNW2 ; it's not a digit -- quit 5012 06672 1372 TAD [-9.] ; then compare it to the other end 5013 06673 7740 SMA SZA CLA ; ??? 5014 06674 5313 JMP DECNW2 ; still not a digit 5015 5016 ; Accumulate another decimal digit... 5017 06675 1065 TAD WORD ; get the old total 5018 06676 7104 CLL RAL ; multiply it by two 5019 06677 3065 DCA WORD ; and save that 5020 06700 1065 TAD WORD ; ... 5021 06701 7104 CLL RAL ; then multiply it by 4 more 5022 06702 7104 CLL RAL ; (for a total of 8) 5023 06703 1065 TAD WORD ; because 8x + 2x = 10x 5024 06704 1050 TAD SAVCHR ; then add the new digit 5025 06705 1373 TAD [-"0"] ; and correct for ASCII characters 5026 06706 3065 DCA WORD ; remember that for next time 5027 5028 ; Read the next digit and proceed... 5029 06707 2070 ISZ DIGITS ; remember one more digit processed 5030 06710 6205 .PUSHJ @ZGET ; get the next character 06711 5515 5031 06712 5267 JMP DECNW1 ; then keep trying 5032 5033 ; Here when we find something which isn't a digit... 5034 06713 7200 DECNW2: CLA ; ... 5035 06714 1070 TAD DIGITS ; get the digit count 5036 06715 7650 SNA CLA ; it has to be at least one 5037 06716 5525 JMP @ZCOMERR ; that's an error if it isn't 5038 06717 6225 .POPJ ; and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 122 Scan Octal Numbers BTS6120.plx 5039 .TITLE Scan Octal Numbers 5040 5041 5042 ; This routine will read an octal number from the command line and return 5043 ; its value in location WORD. The value is usually limited to twelve bits, 5044 ; however any overflow bits will be left in location WORDH. This is intended 5045 ; for use by the OCTNF routine to extract the field from a 15 bit address. 5046 ; At least one octal digit must be found on the command line or COMERR will be 5047 ; called, and the first non-digit character found will be returned in location 5048 ; SAVCHR. 5049 06720 7200 OCTNW: CLA ; remove any junk 5050 06721 3065 DCA WORD ; clear the partial total 5051 06722 3070 DCA DIGITS ; we haven't read any digits yet 5052 06723 6205 .PUSHJ @ZSPACMP ; ignore any leading spaces 06724 5510 5053 5054 ; Check for an octal digit next... 5055 06725 1373 OCTN1: TAD [-"0"] ; compare it to a zero 5056 06726 7510 SPA ; ??? 5057 06727 5350 JMP OCTN2 ; this one isn't a digit 5058 06730 1371 TAD [-7] ; now compare to the high end of the range 5059 06731 7740 SMA SZA CLA ; ??? 5060 06732 5350 JMP OCTN2 ; still not a digit 5061 5062 ; Now accumulate another digit. 5063 06733 1065 TAD WORD ; get the previous total 5064 06734 3066 DCA WORDH ; and remember that for OCTNF 5065 06735 1065 TAD WORD ; then again 5066 06736 7006 RTL ; shift it left 3 bits 5067 06737 7004 RAL ; ... 5068 06740 0370 AND [7770] ; then insure that no junk has wrapped around 5069 06741 1050 TAD SAVCHR ; add the next digit 5070 06742 1373 TAD [-"0"] ; and correct for ASCII values 5071 06743 3065 DCA WORD ; remember the new total 5072 06744 2070 ISZ DIGITS ; also remember how many digits we read 5073 06745 6205 .PUSHJ @ZGET ; read the next character 06746 5515 5074 06747 5325 JMP OCTN1 ; then go look for more 5075 5076 ; Here when we find something which isn't a digit... 5077 06750 7200 OCTN2: CLA ; ... 5078 06751 1070 TAD DIGITS ; see how many digits we've read 5079 06752 7650 SNA CLA ; there must be at least one 5080 06753 5525 JMP @ZCOMERR ; nope -- this isn't legal 5081 06754 6225 .POPJ ; and return that in the AC 5082 06770 7770 06771 7771 06772 7767 06773 7720 06774 0133 06775 7746 06776 0101 06777 7677 5083 07000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 123 Scan 15 Bit Addresses BTS6120.plx 5084 .TITLE Scan 15 Bit Addresses 5085 5086 5087 ; This routine will read a 15 bit address from the command. The lower 12 5088 ; bits of the address are always left in location WORD, and the upper 3 bits 5089 ; will be in location ADRFLD, properly justified. If the user types 5 or more 5090 ; digits in the octal address, the lower 12 bits becomes the address, and the 5091 ; next 3 most significant bits are the field. If his octal number has 4 or 5092 ; fewer digits, the field will be the current data field instead. For example, 5093 ; (assume that the current DF is 3): 5094 ; 5095 ; 1234 --> Location 1234, field 3 5096 ; 01234 --> Location 1234, field 0 5097 ; 41234 --> Location 1234, field 4 5098 ; 5641234 --> Location 1234, field 4 5099 ; 5100 ; Like the OCTNW routine, this routine will return the low order 12 bits 5101 ; in location WORD. There is an alternate entry point at location OCTNI; this 5102 ; is identical to OCTNF, except that the instruction field, not the data field, 5103 ; provides the default field number... 5104 5105 ; Here to read an address in the instruction field... 5106 07000 7200 OCTNI: CLA ; ... 5107 07001 1002 TAD UFLAGS ; use the instruction field as default 5108 07002 0131 AND ZK70 ; ... 5109 07003 5210 JMP OCTNF1 ; then proceed normally 5110 5111 ; Here to read an address in the data field... 5112 07004 7200 OCTNF: CLA ; ... 5113 07005 1002 TAD UFLAGS ; use the data field as the default 5114 07006 7014 R3L ; ... 5115 07007 0131 AND ZK70 ; ... 5116 07010 3036 OCTNF1: DCA ADRFLD ; and save the default for later 5117 07011 6205 .PUSHJ @ZOCTNW ; read a normal octal number 07012 5516 5118 07013 7200 CLA ; we don't care about this part 5119 07014 1070 TAD DIGITS ; see how many digits there were 5120 07015 1377 TAD [-5] ; we need at least 5 5121 07016 7710 SPA CLA ; ??? 5122 07017 6225 .POPJ ; there weren't that many -- use the default 5123 5124 ; Extract the upper 3 bits of the address... 5125 07020 1066 TAD WORDH ; get the high order bits 5126 07021 7002 BSW ; then put the upper 3 bits in the right place 5127 07022 0131 AND ZK70 ; trim it to just the important bits 5128 07023 3036 DCA ADRFLD ; then that is the new data field (temporarily) 5129 07024 6225 .POPJ ; that's all folks PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 124 Ask For Confirmation BTS6120.plx 5130 .TITLE Ask For Confirmation 5131 5132 5133 ; This routine will type a question mark and then wait for the operator to 5134 ; enter a "Y" (or "y") to confirm. It's used by exceptionally dangerous 5135 ; commands, like FORMAT, and normally the caller will type a short string 5136 ; (e.g. "Format unit 0" before actually calling this function. If the 5137 ; operator does confirm, it will return with the link set. If the operator 5138 ; types anything other than "Y" or "y", it will return with the link clear. 5139 ; Note that it's also acceptable to just type Control-C to abort! 5140 07025 6205 CONFRM: .PUSHJ @[TQUEST] ; type a question mark 07026 5776 5141 07027 6205 CONF1: .PUSHJ @[INCHRS] ; go get a character of input 07030 5775 5142 07031 7450 SNA ; did we get anything ? 5143 07032 5227 JMP CONF1 ; nope - keep waiting 5144 07033 3050 DCA SAVCHR ; we got a real character - save it 5145 07034 1050 TAD SAVCHR ; and echo it back to the terminal 5146 07035 6205 .PUSHJ @ZOUTCHR ; ... 07036 5474 5147 07037 6205 .PUSHJ @ZCRLF ; followed by a CRLF 07040 5506 5148 5149 ; See what his answer was... 5150 07041 1050 TAD SAVCHR ; get the answer once more 5151 07042 1374 TAD [-"Y"] ; is it a "Y" 5152 07043 7450 SNA ; ??? 5153 07044 5252 JMP CONF2 ; yes - return with the link set 5154 07045 1373 TAD ["Y"-"y"] ; or a "y"? 5155 07046 7450 SNA ; ??? 5156 07047 5252 JMP CONF2 ; yes - same thing 5157 07050 7300 CLA CLL ; nope - return FALSE 5158 07051 6225 .POPJ 5159 5160 ; Here if he answered "Y" or "y"... 5161 07052 7320 CONF2: CLA STL ; return TRUE 5162 07053 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 125 Type Special Characters BTS6120.plx 5163 .TITLE Type Special Characters 5164 5165 5166 ; This routine will simulate a TAB on the terminal, which it does by typing 5167 ; spaces until the horizontal position reaches a multiple of 8 characters. 5168 ; Note that this routine will always type at least one space. The AC is 5169 ; always cleared by this routine. 5170 07054 6205 TTABC: .PUSHJ TSPACE ; Always type at least one space 07055 5263 5171 07056 1053 TAD HPOS ; Get the current horizontal position 5172 07057 0132 AND ZK7 ; Is it a multiple of 8 ?? 5173 07060 7640 SZA CLA ; ??? 5174 07061 5254 JMP TTABC ; No -- keep typing 5175 07062 6225 .POPJ ; Yes -- we can stop now 5176 5177 ; This routine will type a space on the terminal. 5178 07063 7200 TSPACE: CLA ; Clear the AC 5179 07064 1372 TAD [" "] ; And load a space character 5180 07065 5771 JMP @[THCHAR] ; Then type it and return 5181 5182 ; This routine will type a question mark on the terminal. 5183 07066 7200 TQUEST: CLA ; ... 5184 07067 1370 TAD ["?"] ; ... 5185 07070 5771 JMP @[THCHAR] ; ... 5186 5187 ; This routine will type a BELL character on the terminal. 5188 07071 7200 TBELL: CLA ; ... 5189 07072 1367 TAD [CHBEL] ; Get a bell character 5190 07073 5766 JMP @[TFCHAR] ; Then type it out 5191 5192 ; Type a slash (used as an address separator) on the terminal. 5193 07074 7200 TSLASH: CLA ; ... 5194 07075 1365 TAD ["/"] ; ... 5195 07076 5771 JMP @[THCHAR] ; ... 5196 5197 ; Type a dot (used for decimal numbers and disk addresses) on the terminal. 5198 07077 7200 TDOT: CLA ; ... 5199 07100 1364 TAD ["."] ; ... 5200 07101 5771 JMP @[THCHAR] ; ... 5201 5202 ; Convert the value in the AC to a decimal digit and type it... 5203 07102 1363 TDIGIT: TAD ["0"] ; make it ASCII 5204 07103 5771 JMP @[THCHAR] ; type it and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 126 Type Carriage Return, Line Feed and Backspace BTS6120.plx 5205 .TITLE Type Carriage Return, Line Feed and Backspace 5206 5207 5208 ; This routine will type a carriage return, line feed pair on the terminal 5209 ; and it will correctly update HPOS to show that the cursor is now at the left 5210 ; margin. In addition, it will keep count of the number of CRLFs output in 5211 ; location VPOS, and when the terminal's screen is full (as indicated by VPOS 5212 ; equals LENGTH) it will cause an automatic XOFF. The AC is always cleared 5213 ; on return. 5214 07104 7200 CRLF: CLA ; be sure the AC is cleared 5215 07105 1362 TAD [CHCRT] ; get a return character 5216 07106 6205 .PUSHJ @[TFCHAR] ; and type that out 07107 5766 5217 07110 3053 DCA HPOS ; remember that the cursor is in column zero 5218 5219 ; Now check the vertical position of the cursor... 5220 07111 2054 ISZ VPOS ; increment the current position 5221 07112 7000 NOP ; ... 5222 07113 1031 TAD LENGTH ; get the size of the screen 5223 07114 7450 SNA ; is it zero ?? 5224 07115 5327 JMP CRLF1 ; yes -- never stop 5225 07116 7041 CIA ; no -- make it negative 5226 07117 1054 TAD VPOS ; and compare it to the current location 5227 07120 7710 SPA CLA ; is the screen full ?? 5228 07121 5327 JMP CRLF1 ; no -- proceed 5229 07122 3054 DCA VPOS ; yes -- clear the vertical position 5230 07123 6205 .PUSHJ @[TBELL] ; type a bell character 07124 5761 5231 07125 7240 STA ; then load a -1 into the AC 5232 07126 3052 DCA XOFF ; and cause an automatic XOFF 5233 5234 ; Type the line feed next... 5235 07127 1360 CRLF1: TAD [CHLFD] ; now get a line feed 5236 07130 5766 JMP @[TFCHAR] ; type that and return 5237 5238 ; This routine will type a BACKSPACE character on the terminal and update 5239 ; HPOS to show the new cursor position. It will not allow you to backspace 5240 ; beyond the left margin of the temrinal. The AC is always cleared on return. 5241 07131 7240 TBACKS: STA ; load the AC with -1 5242 07132 1053 TAD HPOS ; and decrement HPOS 5243 07133 7510 SPA ; are we going to pass the left margin ?? 5244 07134 5341 JMP BACKS1 ; yes -- don't type anything 5245 07135 3053 DCA HPOS ; no -- update HPOS 5246 07136 1357 TAD [CHBSP] ; then get a backspace character 5247 07137 6205 .PUSHJ @[TFCHAR] ; and type that out 07140 5766 5248 07141 7200 BACKS1: CLA ; clear the AC 5249 07142 6225 .POPJ ; and that's all 5250 07157 0010 07160 0012 07161 7071 07162 0015 07163 0060 07164 0056 07165 0057 07166 7444 07167 0007 07170 0077 07171 7427 07172 0040 07173 7740 07174 7647 07175 7477 07176 7066 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 127 Type Carriage Return, Line Feed and Backspace BTS6120.plx 07177 7773 5251 07200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 128 Read Command Lines BTS6120.plx 5252 .TITLE Read Command Lines 5253 5254 5255 ; This routine will read a single command line from the user and store the 5256 ; text of the line, one character per word and terminated by a null character, 5257 ; in the array at CMDBUF. The size of CMDBUF, and therefore the maximum 5258 ; length of a command, is given by MAXCMD and is normally a page (128 words). 5259 ; An auto-index register, L, is set aside just for the purpose of indexing the 5260 ; command buffer and when it returns this routine will always leave L set up 5261 ; to point to the beginning of the command. 5262 ; 5263 ; While it is reading the command, this routine will recognize these control 5264 ; characters: 5265 ; 5266 ; Control-C --> Abort the command 5267 ; Control-R --> Retype the current line, including corrections 5268 ; Control-U --> Erase the current line and start over again 5269 ; DELETE --> Erase the last character (echos the last character typed) 5270 ; BACKSPACE --> Erase the last character on a CRT 5271 ; Return --> Terminates the current command 5272 ; Line Feed --> " " " " 5273 ; ESCAPE --> " " " " 5274 ; 5275 ; When this routine is called, the AC should contain the prompting 5276 ; character. 5277 ; 5278 ; The calling sequence for INCHWL goes something like this: 5279 ; 5280 ; TAD ["x"] ; load the prompting character 5281 ; .PUSHJ @[INCHWL] ; and initialize the command scanner 5282 ; NXTCHR: .PUSHJ @[INCHW1] ; read and process the next character 5283 ; SNA CLA ; did we find the EOL? 5284 ; JMP NEXT ; no - keep processing 5285 ; 5286 ; 5287 ; The reason for this rather awkward sequence is that it allows the caller 5288 ; to add background processing to the character input loop (by inserting 5289 ; it at NXTCHR:). The main command scanner, for example, uses this to 5290 ; poll the front panel switches while we're waiting for input. 5291 5292 ; Call here first to initialize the scanner... 5293 07200 3141 INCHWL: DCA PROMPT ; remember the prompt character 5294 07201 1377 TAD [CMDBUF-1] ; point to the line buffer 5295 07202 3013 DCA L ; and initialize the pointer 5296 07203 3140 DCA CMDLEN ; say that this command is zero characters 5297 07204 3052 DCA XOFF ; clear the XOFF and 5298 07205 3051 DCA CTRLO ; control-O flags... 5299 07206 1141 TAD PROMPT ; get the prompting address back again 5300 07207 5474 JMP @ZOUTCHR ; type the prompt and return 5301 5302 ; Then call here to read and process the next character... 5303 07210 6205 INCHW1: .PUSHJ @[INCHRS] ; try to read something from the console 07211 5776 5304 07212 7450 SNA ; did we get anything ?? 5305 07213 6225 .POPJ ; no - return with the AC cleared 5306 07214 3050 DCA SAVCHR ; save this character for a while 5307 07215 3052 DCA XOFF ; then clear the XOFF, 5308 07216 3051 DCA CTRLO ; control-O, and 5309 07217 3054 DCA VPOS ; automatic XOFF flags 5310 07220 1050 TAD SAVCHR ; get the character back 5311 07221 1133 TAD ZMSPACE ; compare this to a space 5312 07222 7510 SPA ; ??? 5313 07223 5242 JMP INCHW3 ; this is a control character 5314 07224 1375 TAD [" "-177] ; is this a DELETE character ? 5315 07225 7650 SNA CLA ; ??? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 129 Read Command Lines BTS6120.plx 5316 07226 5335 JMP INCHW8 ; yes -- go do that 5317 5318 ; Here to process a normal character... 5319 07227 1140 INCHW2: TAD CMDLEN ; get the length of this line 5320 07230 1374 TAD [-MAXCMD] ; and compare to the maximum 5321 07231 7700 SMA CLA ; are we already full ?? 5322 07232 5356 JMP INCH10 ; yes -- don't store this character 5323 07233 1050 TAD SAVCHR ; get the character back 5324 07234 6205 .PUSHJ @ZOUTCHR ; and echo it to the terminal 07235 5474 5325 07236 1050 TAD SAVCHR ; get the character again 5326 07237 3413 DCA @L ; store it in the line 5327 07240 2140 ISZ CMDLEN ; the command is one character longer now 5328 07241 5210 JMP INCHW1 ; and go get the next one 5329 5330 ; Here to handle a control-R command... 5331 07242 1373 INCHW3: TAD [" "-CHCTR] ; is this really a control-R ?? 5332 07243 7440 SZA ; ??? 5333 07244 5264 JMP INCHW4 ; no -- Proceed 5334 07245 3413 DCA @L ; yes -- close the command buffer 5335 07246 1372 TAD [CHCTR] ; get the control-R character back 5336 07247 6205 .PUSHJ @ZOUTCHR ; and echo that to the terminal 07250 5474 5337 07251 6205 .PUSHJ @ZCRLF ; start a new line 07252 5506 5338 07253 1141 TAD PROMPT ; get the prompt character first 5339 07254 6205 .PUSHJ @ZOUTCHR ; and always type that too 07255 5474 5340 07256 1377 TAD [CMDBUF-1] ; point to the current command 5341 07257 6205 .PUSHJ @[TASCIZ] ; and echo the entire line back 07260 5771 5342 07261 6205 .PUSHJ @ZBACKUP ; backup L over the null we put there 07262 5512 5343 07263 5210 JMP INCHW1 ; finally continue typing 5344 5345 ; Here to handle a Control-U character... 5346 07264 1370 INCHW4: TAD [CHCTR-CHCTU] ; is this really a Control-U character ?? 5347 07265 7440 SZA ; ??? 5348 07266 5275 JMP INCHW5 ; no -- keep trying 5349 07267 1367 TAD [CHCTU] ; yes -- get the character back again 5350 07270 6205 .PUSHJ @ZOUTCHR ; and echo that to the operator 07271 5474 5351 07272 6205 .PUSHJ @ZCRLF ; then start on a new line 07273 5506 5352 07274 5201 JMP INCHWL+1 ; and go start all over again 5353 5354 ; Here to handle a BACKSPACE character... 5355 07275 1366 INCHW5: TAD [CHCTU-CHBSP] ; is that what this is ?? 5356 07276 7440 SZA ; ??? 5357 07277 5312 JMP INCHW6 ; nope, not yet 5358 07300 1140 INCHBS: TAD CMDLEN ; yes -- get the length of this command 5359 07301 7650 SNA CLA ; is it a null line ?? 5360 07302 5210 JMP INCHW1 ; yes -- there's nothing to delete 5361 07303 6205 .PUSHJ @ZBACKS ; yes, type a backspace 07304 5476 5362 07305 6205 .PUSHJ @ZTSPACE ; then type a space 07306 5475 5363 07307 6205 .PUSHJ @ZBACKS ; and another backspace 07310 5476 5364 07311 5350 JMP INCHW9 ; finally join with the DELETE code 5365 5366 ; Here to check for line terminators... 5367 07312 1365 INCHW6: TAD [CHBSP-CHCRT] ; is this a return ?? 5368 07313 7450 SNA ; ??? 5369 07314 5326 JMP INCHW7 ; yes -- this line is done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 130 Read Command Lines BTS6120.plx 5370 07315 1364 TAD [CHCRT-CHLFD] ; no -- Is it a line feed then ? 5371 07316 7450 SNA ; ??? 5372 07317 5326 JMP INCHW7 ; yes -- That's just as good 5373 07320 1363 TAD [CHLFD-CHESC] ; no -- How about an escape ? 5374 07321 7640 SZA CLA ; ??? 5375 07322 5227 JMP INCHW2 ; no -- just store this control character 5376 5377 ; Here to finish a command... 5378 07323 1362 TAD [CHESC] ; get the ESCAPE code back 5379 07324 6205 .PUSHJ @ZOUTCHR ; and echo that to the terminal 07325 5474 5380 07326 6205 INCHW7: .PUSHJ @ZCRLF ; then close the input line 07327 5506 5381 07330 3413 DCA @L ; end the command with a null byte 5382 07331 1377 TAD [CMDBUF-1] ; and then backup the pointer 5383 07332 3013 DCA L ; to the start of the command 5384 07333 7240 STA ; return with the AC non-zero 5385 07334 6225 .POPJ ; that's all there is to it 5386 5387 ; Here to process a DELETE character... 5388 07335 1032 INCHW8: TAD SCOPE ; is the scope flag set? 5389 07336 7640 SZA CLA 5390 07337 5300 JMP INCHBS ; yes - treat as a backspace 5391 07340 1140 TAD CMDLEN ; get the command length 5392 07341 7650 SNA CLA ; is this a null command ?? 5393 07342 5210 JMP INCHW1 ; yes -- there's nothing to delete 5394 07343 6205 .PUSHJ @ZBACKUP ; decrement the line pointer 07344 5512 5395 07345 1413 TAD @L ; get the last character stored 5396 07346 6205 .PUSHJ @ZOUTCHR ; and echo that for the DELETE 07347 5474 5397 5398 ; Now delete the last character typed... 5399 07350 6205 INCHW9: .PUSHJ @ZBACKUP ; decrement the line pointer 07351 5512 5400 07352 7240 STA ; then fix the command length too 5401 07353 1140 TAD CMDLEN ; ... 5402 07354 3140 DCA CMDLEN ; ... 5403 07355 5210 JMP INCHW1 ; finally go get the next character 5404 5405 ; Here if the command line is full -- echo a bell instead... 5406 07356 6205 INCH10: .PUSHJ @[TBELL] ; go type a bell character 07357 5761 5407 07360 5210 JMP INCHW1 ; then go wait for something to do 5408 07361 7071 07362 0033 07363 7757 07364 0003 07365 7773 07366 0015 07367 0025 07370 7775 07371 6246 07372 0022 07373 0016 07374 7631 07375 7641 07376 7477 07377 0230 5409 07400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 131 Terminal Output Primitives BTS6120.plx 5410 .TITLE Terminal Output Primitives 5411 5412 5413 ; This routine will type the character in the AC on on the terminal. If the 5414 ; character is a printing character, it will be typed normally. If this 5415 ; character is happens to be a DELETE or NULL code (ASCII codes 00 and 7F), 5416 ; it will be ignored. If the character is a TAB, it is simulated by calling 5417 ; the TTABC routine. Finally, if it is any other control character, it is 5418 ; converted to the familiar ^x representation (unless it is an ESCAPE code, 5419 ; which, by tradition, is typed as $). This routine cannot be used to type 5420 ; carriage returns, line feeds, bells, or other control characters that are 5421 ; to be output literally. The AC is always cleared on return. 5422 07400 7450 OUTCHR: SNA ; first see if this character is a null 5423 07401 6225 .POPJ ; just drop it if it is 5424 07402 1133 TAD ZMSPACE ; see if this is a control character 5425 07403 7500 SMA ; skip if it is a control code 5426 07404 5226 JMP OUTCH3 ; just type a normal character 5427 5428 ; Here to type a TAB character... 5429 07405 1377 TAD [" "-CHTAB] ; is this really a TAB character at all ?? 5430 07406 7440 SZA ; ??? 5431 07407 5211 JMP OUTCH1 ; no -- check further 5432 07410 5776 JMP @[TTABC] ; yes -- type a TAB and return 5433 5434 ; Here to print an ESCAPE character... 5435 07411 1375 OUTCH1: TAD [CHTAB-CHESC] ; is this an ESCAPE character ?? 5436 07412 7440 SZA ; ??? 5437 07413 5216 JMP OUTCH2 ; no -- go type the ^x form instead 5438 07414 1374 TAD ["$"] ; yes -- type a dollar sign for an ESCAPE 5439 07415 5227 JMP THCHAR ; then type it and return 5440 5441 ; Here to print a control character... 5442 07416 6215 OUTCH2: .PUSH ; save the character for a while 5443 07417 7200 CLA ; and get the flag character 5444 07420 1373 TAD ["^"] ; ... 5445 07421 6205 .PUSHJ TFCHAR ; type that first 07422 5244 5446 07423 6235 .POP ; then get the character back 5447 07424 1372 TAD [CHESC+"@"] ; convert it to a printing character 5448 07425 5227 JMP THCHAR ; type that and return 5449 5450 ; Here to print a normal character... 5451 07426 1371 OUTCH3: TAD [" "] ; restore the original character 5452 ; and fall into THCHAR 5453 5454 5455 ; This routine will type a printing character and, while doing this, it will 5456 ; keep track of the horizontal position of the cursor. If it passes the line 5457 ; length of the terminal, a free carriage return is also typed. The terminal's 5458 ; horizontal position (HPOS) is also used for the tab simulation. The 5459 ; character to be typed should be in the AC, the AC will be cleared on return. 5460 07427 6215 THCHAR: .PUSH ; save the character for a while 5461 07430 2053 ISZ HPOS ; and incrment the horizontal position 5462 07431 7200 CLA ; get the maximum width allowed 5463 07432 1030 TAD WIDTH ; ... 5464 07433 7450 SNA ; is it zero ?? 5465 07434 5243 JMP THCHA1 ; yes -- no automatic carriage returns, then 5466 07435 7041 CMA CIA ; make it negative 5467 07436 1053 TAD HPOS ; and compare to the terminal cursor position 5468 07437 7710 SPA CLA ; have we reached the end of the line ?? 5469 07440 5243 JMP THCHA1 ; no -- proceed normally 5470 07441 6205 .PUSHJ @ZCRLF ; yes -- force a carriage return first 07442 5506 5471 07443 6235 THCHA1: .POP ; then get the character back 5472 ; and fall into TFCHAR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 132 Terminal Output Primitives BTS6120.plx 5473 5474 5475 ; This routine will type a single character from the AC on the terminal. 5476 ; Before it types the character, this routine will check the state of the 5477 ; CNTRLO and XOFF flags. If a Control-O has been typed, the character is 5478 ; discarded and not typed on the terminal. If an XOFF has been typed, the 5479 ; output will be suspended until the user types an XON character (or a 5480 ; Control-O or Control-C). 5481 07444 6215 TFCHAR: .PUSH ; save the character for a while 5482 07445 6205 TFCHA1: .PUSHJ INCHRS ; check the operator for input 07446 5277 5483 07447 7200 CLA ; we don't care if anything was typed 5484 07450 1051 TAD CTRLO ; get the Control-O flag byte 5485 07451 7640 SZA CLA ; is it zero ?? 5486 07452 5260 JMP TFCHA2 ; no -- just throw this character away 5487 07453 1052 TAD XOFF ; now test the XOFF flag 5488 07454 7640 SZA CLA ; is the output suspended ?? 5489 07455 5245 JMP TFCHA1 ; wait for something to happen if we are XOFFed 5490 5491 ; Here when it is OK to type the character... 5492 07456 6235 .POP ; get the character back 5493 07457 5263 JMP CONOUT ; and send it to the UART 5494 5495 ; Here to return without typing anything... 5496 07460 6235 TFCHA2: .POP ; clean up the stack 5497 07461 7200 CLA ; but always return zero 5498 07462 6225 .POPJ ; and just quit 5499 5500 ; This routine will output a character from the AC to the terminal, with no 5501 ; no special processing of any kind. It simply waits for the console flag to 5502 ; set and then send the character. However, If the flag does not set in a 5503 ; reasonable amount of time then this routine will force the character out 5504 ; anyway. This prevents the monitor from hanging if the terminal flag is 5505 ; cleared by the user's program. 5506 ; 5507 ; The timeout loop requires 26 minor cycles which, with a 4.9152Mhz clock, 5508 ; takes 10.5 microseconds. If we simply clear the timeout counter when we 5509 ; start we'll get a timeout after 4096 counts, or about 43 milliseconds. 5510 ; If we assume that 300 baud is the slowest console we'll ever use, then 5511 ; that's just about right (at 300 baud a character takes about 33 milliseconds 5512 ; to transmit!). 5513 ; 5514 07463 3276 CONOUT: DCA CONCHR ; remember the character to send 5515 07464 3055 DCA IRMA ; and clear the timeout timer 5516 5517 ; See if the flag is set and send the character if so... 5518 07465 6041 CONOU1: TSF ; [9] is the flag set ??? 5519 07466 5273 JMP CONOU3 ; [4] no -- go check the timeout 5520 07467 1276 CONOU2: TAD CONCHR ; yes -- get the character 5521 07470 6046 TLS ; and send it to the console 5522 07471 7200 CLA ; a _real_ TLS doesn't clear the AC!! 5523 ;; .POPJ ; ... 5524 07472 5770 JMP @[UPDISP] ; keep the front panel display alive and exit 5525 5526 ; Here if the flag is not yet set... 5527 07473 2055 CONOU3: ISZ IRMA ; [9] have we waited long enough ??? 5528 07474 5265 JMP CONOU1 ; [4] no -- wait a little longer 5529 07475 5267 JMP CONOU2 ; yes -- force the character out anyway 5530 5531 ; Temporary storage for the CONOUT routine... 5532 07476 CONCHR: .BLOCK 1 ; a place to save the console character PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 133 Terminal Input Primitives BTS6120.plx 5533 .TITLE Terminal Input Primitives 5534 5535 5536 ; This routine is called to check for operator input. It will test to see 5537 ; if the operator has typed a character. If he has not, this routine returns 5538 ; with the AC cleared and nothing else happens. If he has, this routine checks 5539 ; to see if the character is one of Control-C, Control-O, Control-S or 5540 ; Control-Q because these characters have special meaning and are acted upon 5541 ; immediately. If the input character is anything else, the character is 5542 ; returned in the AC. 5543 07477 6205 INCHRS: .PUSHJ @[UPDISP] ; keep the front panel display alive 07500 5770 5544 07501 6205 .PUSHJ CONIN ; try to read a character from the terminal 07502 5352 5545 07503 0130 AND ZK177 ; ignore the parity bit here 5546 07504 7450 SNA ; is this a null character ?? 5547 07505 6225 .POPJ ; yes -- just ignore it 5548 5549 ; Here process a control-C character -- restart the monitor... 5550 07506 1367 TAD [-CHCTC] ; is this really a control-C ?? 5551 07507 7440 SZA ; ??? 5552 07510 5317 JMP INCHR1 ; no -- proceed 5553 07511 3051 DCA CTRLO ; yes -- clear the control-O 5554 07512 3052 DCA XOFF ; and XOFF flags 5555 07513 1366 TAD [CHCTC] ; get another control-C character 5556 07514 6205 .PUSHJ @ZOUTCHR ; echo it to the terminal 07515 5474 5557 07516 5524 JMP @ZRESTA ; and go restart the monitor 5558 5559 ; Here to check for a control-O character... 5560 07517 1365 INCHR1: TAD [CHCTC-CHCTO] ; compare to a control-O character 5561 07520 7440 SZA ; is this it ?? 5562 07521 5334 JMP INCHR2 ; no -- keep checking 5563 07522 3052 DCA XOFF ; control-O always clears the XOFF flag 5564 07523 1364 TAD [CHCTO] ; get another control-O character 5565 07524 6205 .PUSHJ @ZOUTCHR ; and echo that 07525 5474 5566 07526 6205 .PUSHJ @ZCRLF ; then close the line 07527 5506 5567 07530 1051 TAD CTRLO ; get the current state of the control-O flag 5568 07531 7040 CMA ; and complement it 5569 07532 3051 DCA CTRLO ; that's the new value 5570 07533 6225 .POPJ ; return with the AC cleared 5571 5572 ; Here to check for a control-S character... 5573 07534 1363 INCHR2: TAD [CHCTO-CHXOF] ; is this a control-S ?? 5574 07535 7440 SZA ; ??? 5575 07536 5342 JMP INCHR3 ; nope, try again 5576 07537 7240 STA ; yes -- get a -1 into the AC 5577 07540 3052 DCA XOFF ; and set the XOFF flag 5578 07541 6225 .POPJ ; return with the AC cleared 5579 5580 ; Here to check for a control-Q character... 5581 07542 1362 INCHR3: TAD [CHXOF-CHXON] ; is this a control-Q ?? 5582 07543 7440 SZA ; ??? 5583 07544 5350 JMP INCHR4 ; no -- just give up 5584 07545 3052 DCA XOFF ; yes -- clear the XOFF flag 5585 07546 3054 DCA VPOS ; also clear the automatic XOFF counter 5586 07547 6225 .POPJ ; return with the AC cleared 5587 5588 ; Here if the character is nothing special... 5589 07550 1361 INCHR4: TAD [CHXON] ; restore the state of the AC 5590 07551 6225 .POPJ ; and return the character in the AC 5591 5592 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 134 Terminal Input Primitives BTS6120.plx 5593 ; This routine will read a single character from the console UART. If no 5594 ; character is currently ready, it will return a null (zero) byte in the AC, 5595 ; but otherwise the character read is left in the AC... 5596 07552 7200 CONIN: CLA ; be sure the AC is cleared 5597 07553 6031 KSF ; is a character ready ?? 5598 07554 6225 .POPJ ; no -- just return zero 5599 07555 6036 KRB ; yes -- read it into the AC 5600 07556 6225 .POPJ ; then return that in the AC 5601 07561 0021 07562 0002 07563 7774 07564 0017 07565 7764 07566 0003 07567 7775 07570 6044 07571 0040 07572 0133 07573 0136 07574 0044 07575 7756 07576 7054 07577 0027 5602 07600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 135 Control Panel Entry Points BTS6120.plx 5603 .TITLE Control Panel Entry Points 5604 5605 07600 .ORG 7600 5606 5607 ; There's a little bit of chicanery that goes on here (when have you seen 5608 ; a PDP-8 program without that???). After a power on clear or a hard reset, 5609 ; the HM6120 starts executing at location 7777 of panel memory which, in 5610 ; the case of the SBC6120, is part of the EPROM. The EPROM code at this 5611 ; location always jumps to the system initialization routine without even 5612 ; trying to figure out why we entered panel mode. 5613 ; 5614 ; The system initialization code copies all of the EPROM contents to panel 5615 ; RAM and then disables the EPROM forever. After that it actually changes 5616 ; the vector at location 7777 to point to the CPSAVE routine, which is the 5617 ; normal panel entry point for traps, halts, etc. 5618 7600 .VECTOR CPBOOT ; set the 6120 start up vector at 7777 5619 07600 6213 CPBOOT: CXF 1 ; the startup code lives in field 1 5620 07601 5776 JMP @[SYSINI] ; and away we go! 5621 5622 5623 ; Excluding a hardware reset, the 6120 will enter control panel mode for any 5624 ; of three other reasons: 5625 ; 5626 ; * any of the PR0..PR3 instructions were executed in main memory 5627 ; * the CPU was halted, either by a HLT instruction or by the RUN/HLT input 5628 ; * a panel interrupt was requested by the CPREQ pin 5629 ; 5630 ; In all the these cases, the 6120 was presumably executing some important 5631 ; program in main memory before it was interrupted, and we need to save the 5632 ; state of that program before doing anything else. When the 6120 enters 5633 ; panel mode it saves the last main memory PC in panel memory location 0 and 5634 ; then starts executing instructions in panel memory at 7777. The remainder of 5635 ; the main memory context (e.g. AC, MQ, flags, etc) we have to save manually. 5636 07602 3001 CPSAVE: DCA UAC ; save the AC 5637 07603 6256 GCF ; and the flags (including LINK, IF and DF) 5638 07604 3002 DCA UFLAGS ; ... 5639 07605 7501 MQA ; the MQ 5640 07606 3003 DCA UMQ ; ... 5641 07607 6207 RSP1 ; 6120 stack pointer #1 5642 07610 3004 DCA USP1 ; ... 5643 07611 6227 RSP2 ; " " " #2 5644 07612 3005 DCA USP2 ; .. 5645 5646 ; Now set up enough context so that this monitor can run. The CONT routine 5647 ; has saved in location STKSAV our last stack pointer before the main memory 5648 ; program was started and, if we're single stepping the main memory program, 5649 ; we're going to need that so that we can continue what we were doing. In 5650 ; the case of other traps the RESTA routine gets called which will reset the 5651 ; stack pointer. 5652 07613 1142 TAD STKSAV ; get the monitor's last known stack pointer 5653 07614 6217 LSP1 ; and restore that 5654 07615 6203 CXF 0 ; set both DF and IF to field zero 5655 07616 5775 JMP @[.+1] ; update the IF and clear the FZ flag 5656 07617 6276 SPD ; make indirect cycles access panel memory 5657 07620 3054 DCA VPOS ; reset the automatic XOFF line counter 5658 07621 6441 POST+1 ; show post code #1 5659 5660 ; Finally, we can determine the exact reason for entry into panel mode by 5661 ; reading the panel status flags with the PRS instruction, and that will tell 5662 ; us where to go next. Be careful, though, because executing PRS clears the 5663 ; flags so we only get to do it once! This code kind of assumes that only one 5664 ; of these flags can be set at any time - I believe that's true for the 6120. 5665 07622 6000 PRS ; get the reason for panel entry 5666 07623 7004 RAL ; BTSTRP -> LINK, PNLTRP -> AC0 5667 07624 7510 SPA ; test PNLTRP first PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 136 Control Panel Entry Points BTS6120.plx 5668 07625 5253 JMP PNLTRP ; yes - a PRn instruction was trapped 5669 07626 7430 SZL ; next check BTSTRP 5670 07627 5236 JMP BTSTRP ; yes - an external CPREQ occurred 5671 07630 7004 RAL ; skip the next bit 5672 07631 7006 RTL ; put PWRON -> LINK, and HLTFLG -> AC0 5673 07632 7510 SPA ; test the HLTFLG bit 5674 07633 5311 JMP HALTED ; yes - a HLT instruction was trapped 5675 ; fall thru if PWRON (or none!) is set 5676 5677 ; If we get here, none of the known panel status bits are set. I don't 5678 ; know what this means, but it can't be good! We also jump here if the 5679 ; PWRON status bit is set. Since this bit can only be set by a hardware 5680 ; reset, and since in the SBC6120 this automatically maps EPROM instead 5681 ; of RAM, we should never see this happen. 5682 07634 4320 PWRON: JMS TRAP ; print a generic 5683 07635 3636 TRPMSG ; "% UNKNOWN TRAP AT ..." message 5684 5685 ; The BTSTRP flag indicates a transition of the CPREQ line, which could 5686 ; indicate that a break was typed on the console terminal, or it could 5687 ; indicate that the front panel (if one is installed) requires service. 5688 07636 BTSTRP: 5689 ; We get a CPREQ if the front panel HALT switch is flipped down (i.e. it 5690 ; makes the RUN -> HALT transition). We treat this case just as we would 5691 ; if a HLT instruction were executed - say "%HALTED AT ..." and start the 5692 ; BTS6120 command scanner. Note that if no front panel hardware is 5693 ; installed the SHSW IOT is a NOP and never skips! 5694 07636 6431 SHSW ; skip on halt switch transition 5695 07637 7410 SKP ; nope... 5696 07640 5311 JMP HALTED ; jump to the halt switch code 5697 ; The SCPT IOT will skip if the 30Hz front panel timer has ticked, which 5698 ; would mean that it's time to update the front panel display. Once again, 5699 ; remember that if no front panel is installed the SCPT IOT is a NOP and 5700 ; never skips, which is fine with us. 5701 07641 6433 SCPT ; skip on 30Hz timer 5702 07642 5246 JMP BTSTR1 ; nope - try something else 5703 07643 6205 .PUSHJ @[UPDISP] ; yes - update the display 07644 5774 5704 07645 5773 JMP @[CONT1] ; and then return to the main program 5705 5706 ; Here for an unknown CPREQ. This could be caused by a framing error 5707 ; (i.e. a BREAK) from the console terminal, or it could be caused by 5708 ; some other (optional) piece or hardware... 5709 07646 7000 BTSTR1: NOP ; patch space for a ROM patch 5710 07647 7000 NOP ; ... 5711 07650 7000 NOP ; ... 5712 07651 4320 JMS TRAP ; print 5713 07652 3602 BRKMSG ; "% BREAK AT ..." and restart 5714 5715 ; The PNLTRP flag indicates that one of the PR0 thru PR3 instructions has 5716 ; been executed, but unfortunately the only way to find out which is to 5717 ; use the last main memory PC to fetch the instruction from memory. Remember 5718 ; that the 6120 will have already incremented the PC by the time we get here, 5719 ; so it's actually one _more_ than the location we want. Currently the PR3 5720 ; instruction is used as a breakpoint trap and PR0 is a generic ROM "monitor 5721 ; call". The other two, PR1 and PR2, are unused. 5722 07653 7240 PNLTRP: STA ; decrement the PC 5723 07654 1000 TAD UPC ; so it points at the actual instruction 5724 07655 3000 DCA UPC ; that caused the trap 5725 07656 1002 TAD UFLAGS ; get the IF at the time of the trap 5726 07657 0131 AND ZK70 ; ... 5727 07660 1271 TAD PNLCDF ; make a CDF instruction out of that 5728 07661 3262 DCA .+1 ; and execute it 5729 07662 7000 NOP ; ... gets overwritten with a CDF ... 5730 07663 6266 CPD ; address main memory with indirect cycles 5731 07664 1000 TAD UPC PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 137 Control Panel Entry Points BTS6120.plx 5732 07665 3006 DCA UIRPC 5733 07666 1400 TAD @UPC ; get the opcode that caused the trap 5734 07667 3007 DCA UIR ; and save it for later 5735 07670 6276 SPD ; back to panel memory 5736 07671 6201 PNLCDF: CDF 0 ; always field zero 5737 5738 ; See which instruction it was... 5739 07672 1007 TAD UIR ; get the opcode 5740 07673 1372 TAD [-BPT] ; is it PR3 ?? 5741 07674 7450 SNA ; ??? 5742 07675 5305 JMP BPTTRP ; yes - handle a break point trap 5743 07676 1371 TAD [BPT-PR0] ; no - is it PR0? 5744 07677 6213 CXF 1 ; (the ROM call handler lives in field 1) 5745 07700 7450 SNA ; ??? 5746 07701 5770 JMP @[MCALL] ; yes - handle a monitor call 5747 07702 6203 CXF 0 ; ... 5748 07703 4320 JMS TRAP ; for any others just print a generic 5749 07704 3612 PRNMSG ; "% PANEL TRAP AT ..." message 5750 5751 ; Here for a breakpoint trap... 5752 07705 4320 BPTTRP: JMS TRAP ; print 5753 07706 3545 BPTMSG ; "% BREAKPOINT AT ..." and proceed 5754 5755 ; Here (from field 1) for an illegal PR0 call... 5756 07707 4320 ILLPR0: JMS TRAP ; say 5757 07710 3560 PR0MSG ; "? ILLEGAL PR0 FUNCTION AT ..." 5758 5759 ; We get here when the 6120 halts, but unfortunately there are no less than 5760 ; three different reasons why it night have done this. The first is that the 5761 ; main memory program has executed a HLT (7402, or any microcoded combination 5762 ; there of) instruction. Or, it could be that the 6120 was halted externally 5763 ; by a transition on the HLTREQ input pin, however the SBC6120 has no hardware 5764 ; to do this. Lastly, it could be that the HALT flag was already set when 5765 ; we restarted the main memory program - in this case the 6120 will execute 5766 ; one instruction and trap back here. 5767 ; 5768 ; We use this situation intentionally to single step main memory programs, 5769 ; and we can tell when this happens by checking the SIMFLG flag in memory. 5770 ; This flag is normally cleared, but will be set by the SINGLE routine when we 5771 ; want to single step. In that case the monitor's stack is valid (it was 5772 ; saved to STKSAV by the CONT routine before switching context) and all we 5773 ; have to do is execute a .POPJ to return to the routine that originally 5774 ; called SINGLE. Keep your fingers crossed. 5775 07711 6435 HALTED: RLOF ; turn the RUN LED off 5776 07712 7200 CLA ; ... 5777 07713 1047 TAD SIMFLG ; did we execute a single instruction? 5778 07714 7640 SZA CLA ; ??? 5779 07715 6225 .POPJ ; yes - return from the SINGLE routine now! 5780 07716 4320 JMS TRAP ; otherwise just say 5781 07717 3625 HLTMSG ; "% HALTED AT ..." and restart 5782 5783 ; This routine does most of the generic work of handling traps to panel 5784 ; memory. It prints a message, which is passed inline via a JMS instruction, 5785 ; prints the PC, removes any breakpoints from the program and then restarts 5786 ; the monitor... 5787 07720 0000 TRAP: 0 ; call here with a JMS instruction 5788 07721 6435 RLOF ; turn the RUN LED off 5789 07722 6205 .PUSHJ @ZCRLF ; be sure we start on a new line 07723 5506 5790 07724 1720 TAD @TRAP ; get the address of the message 5791 07725 6205 .PUSHJ @[OUTSTR] ; and print that 07726 5767 5792 07727 1002 TAD UFLAGS ; then get the field of the trap 5793 07730 0131 AND ZK70 ; ... 5794 07731 6205 .PUSHJ @[TFIELD] ; and type that PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 138 Control Panel Entry Points BTS6120.plx 07732 5766 5795 07733 1000 TAD UPC ; then the PC too 5796 07734 6205 .PUSHJ @ZTOCT4C ; type that and a CRLF 07735 5500 5797 07736 6205 .PUSHJ @[REGLSC] ; type the registers on the next line 07737 5765 5798 07740 6205 .PUSHJ @[BPTRMV] ; remove any breakpoints 07741 5764 5799 07742 6205 .PUSHJ @[EXMEM] ; sync the ADDRESS and DATA displays 07743 5763 5800 07744 5524 JMP @ZRESTA ; and restart the monitor 5801 07763 5751 07764 2123 07765 1240 07766 6412 07767 6200 07770 0201 07771 0030 07772 1542 07773 2227 07774 6044 07775 7617 07776 0001 07777 5200 5802 10200 .FIELD 1 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 139 Field 1 Variables BTS6120.plx 5803 .TITLE Field 1 Variables 5804 5805 5806 ; This page defines all the page zero variables used by the code in field 5807 ; one. The system initialization code, part 1, at SYSINI: also lives in page 5808 ; zero of field one, and then is overwritten by these variables after init- 5809 ; ialization is completed. As a consequence, none of these variables can 5810 ; have initial values the way their field zero counter parts do! 5811 5812 10000 .ORG 0000 5813 5814 10000 F1X0: .BLOCK 1 5815 5816 ; Auto index registers... 5817 10010 .ORG 0010 5818 10010 RAMPTR: .BLOCK 1 ; address, within the RAM disk, for I/O 5819 10011 BUFPTR: .BLOCK 1 ; address of the caller's buffer for I/O 5820 10012 XX1: .BLOCK 1 ; generic auto index register for field 1 5821 10013 XX2: .BLOCK 1 ; " " " " " " 5822 10020 .ORG 0020 5823 5824 ; IDE Disk I/O routine storage... 5825 10020 DKPART: .BLOCK 1 ; 12 bit disk partition number 5826 10021 DKRBN: .BLOCK 1 ; 12 bit sector relative block number 5827 10022 DKSIZE: .BLOCK 1 ; size of attached drive, in MB, or 0 if no drive 5828 10023 DKUNIT: .BLOCK 1 ; logical unit (partition) number for OS/8 5829 5830 ; RAM Disk I/O routine storage... 5831 10024 RDUNIT: .BLOCK 1 ; currently selected RAM disk unit for I/O 5832 10025 RDPAGE: .BLOCK 1 ; " " " " " " page number 5833 10026 RAMBUF: .BLOCK 3 ; a three byte "mini buffer" for 3 <-> 2 packing 5834 10031 RAMDAR: .BLOCK 1 ; RAM disk address register (written to LDAR) 5835 10032 BATTOK: .BLOCK 1 ; -1 -> battery good, 1 -> battery bad, 0 -> unknown 5836 10033 RDSIZE: .BLOCK 10 ; size of each RAM disk unit, in KB, or 0 if none 5837 10043 RAMSIZ: .BLOCK 1 ; total size of all RAM disks, in KB 5838 10044 SIZPTR: .BLOCK 1 ; pointer to the RDSIZE array 5839 10045 RAMUSZ: .BLOCK 1 ; - size of selected RAM disk chip 5840 10046 RDTYPE: .BLOCK 1 ; 0 -> no RAM disk, -1 -> original (DS1221) RAM disk 5841 ; +1 -> new (DS1231) RAM disk, -2 -> IOB6120 RAM disk 5842 5843 ; ROM call arguments 5844 10047 MUUO: .BLOCK 1 ; ROM MCALL function code 5845 10050 ARGPTR: .BLOCK 1 ; pointer to MCALL (PR0) argument list 5846 10051 XFRCNT: .BLOCK 1 ; word count for I/O 5847 10052 BUFPNL: .BLOCK 1 ; -1 if the user buffer is in panel memory 5848 10053 BUFSIZ: .BLOCK 1 ; actual buffer size for RDIBUF/WRIBUF 5849 10054 RWCNT: .BLOCK 1 ; number of pages to be transferred 5850 5851 10200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 140 ROM Calls (PR0 Instructions) BTS6120.plx 5852 .TITLE ROM Calls (PR0 Instructions) 5853 5854 10200 .ORG 0200 5855 5856 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 5857 ; HEX format) stores a checksum of ROM field 1 in location 10200. This is 5858 ; used by the POST and the VE (version) command. 5859 10200 ROMCK1: .BLOCK 1 5860 5861 ; This routine is called by CPSAVE when it detects a panel entry caused by 5862 ; a PR0 instruction. Main memory programs can use this instruction to 5863 ; communicate with the ROM firmware and, in particular, the OS/8 device driver 5864 ; for the RAM disk uses PR0 to transfer data. At this point all of the main 5865 ; memory program's registers have been saved and our original monitor stack 5866 ; has been restored. The data and instruction field are both one and the 5867 ; 6120 panel data flag is set (so indirect references go to panel memory). 5868 ; That's about all we can depend on. 5869 ; 5870 ; There are a couple of subtle points to watch out for here. One simple 5871 ; one is that, to save time, break points are not removed from the caller's 5872 ; program while we interpret a PR0. That means we have to be sure and return 5873 ; to main memory by jumping to CONT1, not CONT, since the latter will attempt 5874 ; to reinstall breakpoints _again_ and forever loose the original contents 5875 ; of those locations. 5876 ; 5877 ; The other thing to remember is that CONT and CPSAVE conspire to preserve 5878 ; the monitor's stack, so that it can return to the correct place while single 5879 ; stepping. That means we want to be sure and JMP to CONT1, not .PUSHJ to it, 5880 ; because otherwise it'll just return back to us the next time we enter panel 5881 ; mode! 5882 ; 5883 ; The convention is that the first word after PR0 is a function code to 5884 ; select the firmware routine. This routine also preserves the contents of 5885 ; the AC both ways - that is, whatever was in the user's AC when the PR0 was 5886 ; executed will be in the AC when our monitor call function is invoked, and 5887 ; whatever our monitor call function returns in the AC will be placed in the 5888 ; user's AC when control returns from the PR0. Anything more than that is up 5889 ; to the specific function invoked. 5890 5891 ; Get the first agument (the function code) and use it to determine the 5892 ; address of a ROM routine to handle it... 5893 10201 6205 MCALL: .PUSHJ GETARG ; CPSAVE leaves the PC pointing at the PR0 10202 5241 5894 ; so do a dummy GETARG to skip it 5895 10203 6205 .PUSHJ GETARG ; then get a real PR0 argument from main memory 10204 5241 5896 10205 3047 DCA MUUO ; this is always the function code 5897 10206 1047 TAD MUUO ; see if it's in range 5898 10207 7100 CLL ; be sure the link is in a known state 5899 10210 1377 TAD [-MAXFUN-1] ; check against the maximum function 5900 10211 7630 SZL CLA ; if it's legal, skip 5901 10212 5237 JMP MCALL2 ; nope - go print an error message... 5902 10213 1047 TAD MUUO ; it's legal - use it 5903 10214 1376 TAD [FUNTBL] ; index into the function dispatch table 5904 10215 3047 DCA MUUO ; ... 5905 10216 1447 TAD @MUUO ; get the address of the function routine 5906 10217 3047 DCA MUUO ; finally - that's what we wanted to know! 5907 5908 ; Invoke the monitor routine, preserving the AC in both directions. In 5909 ; addition, the LINK bit is commonly used as an error flag (i.e. the LINK 5910 ; set on return indicates an error), so it is preserved on return only. 5911 10220 6201 CDF 0 ; the user's context lives in field 0 5912 10221 1775 TAD @[UAC] ; get the user's AC 5913 10222 6211 CDF 1 ; all ROM call routines live in field 1 5914 10223 6205 .PUSHJ @MUUO ; call routine to execute the ROM call PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 141 ROM Calls (PR0 Instructions) BTS6120.plx 10224 5447 5915 10225 6201 MCALL1: CDF 0 ; address the user's context again 5916 10226 3775 DCA @[UAC] ; return whatever's in the AC 5917 10227 7010 RAR ; put the link bit in AC0 5918 10230 3047 DCA MUUO ; save it for a minute 5919 10231 7350 NL3777 ; then mask off the LINK bit 5920 10232 0774 AND @[UFLAGS] ; in the user's flags 5921 10233 1047 TAD MUUO ; and put ours in there instead 5922 10234 3774 DCA @[UFLAGS] ; ... 5923 10235 6203 CXF 0 ; CONT2 lives in field 1 5924 10236 5773 JMP @[CONT2] ; and then return to main memory 5925 5926 ; Here when an illegal PR0 function is invoked. 5927 10237 6203 MCALL2: CXF 0 ; say 5928 10240 5772 JMP @[ILLPR0] ; "?Illegal PR0 function at ..." PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 142 Fetch PR0 Arguments BTS6120.plx 5929 .TITLE Fetch PR0 Arguments 5930 5931 5932 ; This routine fetches an argument for PR0 from the main memory program. 5933 ; Since arguments are always stored in line after the PR0, the next argument 5934 ; is in the instruction field and pointed to by the last main memory PC. 5935 ; After the argument is fetched the main memory PC is always incremented so 5936 ; that we'll skip over the argument when we return - you have to be careful 5937 ; about this, since it means this routine can only be called ONCE to fetch 5938 ; any given argument! The PR0 argument is returned in the AC. 5939 10241 7200 GETARG: CLA 5940 10242 6201 CDF 0 ; BEWARE - UFLAGS and UPC are both in field 0! 5941 10243 1771 TAD @[UPC] ; get the user's PC from field 0 5942 10244 3050 DCA ARGPTR ; save it in field 1 for a moment 5943 10245 2771 ISZ @[UPC] ; and increment it to skip over the argument 5944 10246 7000 NOP ; this really shouldn't ever happen! 5945 10247 1774 TAD @[UFLAGS] ; get the last known user (main memory) flags 5946 10250 0370 AND [70] ; then get the IF at the time of the trap 5947 10251 1367 TAD [CDF 0] ; make a CDF instruction 5948 10252 3253 DCA .+1 ; change to the correct field 5949 10253 7000 NOP ; ... gets overwritten with a CDF ... 5950 10254 6266 CPD ; always fetch from main memory 5951 10255 1450 TAD @ARGPTR ; get the next word from user program space 5952 10256 6276 SPD ; back to panel memory 5953 10257 6211 CDF 1 ; and back to our field 5954 10260 6225 .POPJ ; return the PR0 argument in the AC PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 143 ROM Call Table BTS6120.plx 5955 .TITLE ROM Call Table 5956 5957 5958 ; This is what you've really been waiting for - the table of ROM firmware 5959 ; function codes and routine addresses. 5960 5961 0237 BADFUN=MCALL2 ; illegal function call 5962 5963 10261 0303 FUNTBL: GETVER ; 0 - get ROM version 5964 10262 0310 RAMDRW ; 1 - read/write RAM disk 5965 10263 1000 GETRDS ; 2 - return RAM disk size 5966 10264 0600 GETBAT ; 3 - return RAM disk battery status 5967 10265 2017 DISKRW ; 4 - read/write IDE disk 5968 10266 1131 GETDKS ; 5 - return IDE disk size 5969 10267 1732 SETPMP ; 6 - set disk partition mapping 5970 10270 2000 GETPMP ; 7 - get disk partition mapping 5971 10271 2220 MEMMOV ; 10 - copy memory 5972 10272 2276 MEMMVX ; 11 - copy memory extended 5973 10273 2442 LIGHTS ; 12 - control the DATA LEDs 5974 5975 ; The following six locations are reserved for ROM calls added by the 5976 ; IOB6120 extension ROM. The first three are used by the GETCFS and R/STODC 5977 ; calls, and the remaining four are held for future expansion. If you add 5978 ; more ROM monitor calls the BTS6120, add them _after_ these six! 5979 10274 0237 BADFUN ; 13 - get CompactFlash card size 5980 10275 0237 BADFUN ; 14 - read Time of Day Clock (RTODC) 5981 10276 0237 BADFUN ; 15 - set Time of Day Clock (STODC) 5982 10277 0237 BADFUN ; 16 - (reserved for IOB6120) 5983 10300 0237 BADFUN ; 17 - (reserved for IOB6120) 5984 10301 0237 BADFUN ; 20 - (reserved for IOB6120) 5985 5986 ; Add new BTS6120 calls here... 5987 10302 2456 RDROM ; 21 - read Flash ROM (RDROM) 5988 5989 0021 MAXFUN=.-FUNTBL-1 5990 5991 5992 ; PR0 function zero returns the current firmware version in the AC... 5993 10303 7300 GETVER: CLA CLL ; ... 5994 10304 1366 TAD [VERSION] ; get our version number 5995 10305 6225 .POPJ ; MCALL will store it in the caller's AC 5996 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 144 Return from Routines in Field 1 BTS6120.plx 5997 .TITLE Return from Routines in Field 1 5998 5999 6000 ; This routine is the other half of the code at PUSHJ1:, and it allows 6001 ; routines in field one which were called from field zero to return to 6002 ; field zero. It only needs to do two instructions, but those instructions 6003 ; have to be somewhere in field one! 6004 10306 6203 POPJ1: CXF 0 ; return to field zero 6005 10307 6225 .POPJ ; the address is already on the stack PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 145 RAM Disk support BTS6120.plx 6006 .TITLE RAM Disk support 6007 6008 6009 ; The SBC6120 contains a DS1321 SRAM controller with Li battery backup and 6010 ; sockets for up to eight byte wide SRAM chips. Each socket can contain either 6011 ; a HM628512 512Kx8 SRAM or a HM628128 128Kx8 SRAM or, of course, nothing. 6012 ; Additionally, the last socket has two jumpers which permit a 512K byte 6013 ; CMOS EPROM to be used if desired. The maximum capacity of the RAM disk 6014 ; array is thus 2Mb - a pretty respectable sized disk (almost as big as a 6015 ; RK05J!) for OS/8. 6016 ; 6017 ; The SBC6120 maps these RAM chips into panel memory via the memory decode 6018 ; GAL and, when memory map 3 (MM3) is enabled, all indirect references to panel 6019 ; memory will access the RAM disk array. Since the RAM disk is only a byte 6020 ; wide, write operations discard the upper four bits of a twelve bit word, and 6021 ; when reading these bits are undefined and should be masked off by the 6022 ; software. 6023 ; 6024 ; Addressing the RAM disk is a little tricky, since a 2Mb memory requires 6025 ; a total of 21 address bits - quite a bit more than a PDP-8 can manage. 6026 ; RAM disk address bits 0..11 (the low order bits, contrary to the PDP-8 6027 ; convention) are supplied by the HM6120 MA11-0. The remaining 7 bits needed 6028 ; by each 512K SRAM come from a special register, the Disk Address Register, 6029 ; which can be loaded via the LDAR IOT. The final two bits needed by the 6030 ; DS1321 to select one of the four SRAM chips come from DF0 and DF1. 6031 ; 6032 ; DF2 is used as a "board select" to allow up to two SRAM boards to be 6033 ; installed. Since DF2 is actually the LSB of the data field, the board 6034 ; select is a little wierd - RAM disk units 0..3 are on the first RAM disk 6035 ; board and map to the even fields, 0, 2, 4 and 6. RAM disk units 4..7 are 6036 ; on the second RAM disk board and map to the odd fields - 1, 3, 5 and 7. 6037 ; 6038 ; Put more simply, the DF selects the SRAM chip used, the DAR selects the 6039 ; 4K byte "bank" within the chip, and the normal memory address selects the 6040 ; individual byte within the bank. 6041 ; 6042 ; For the purposes of writing an OS/8 device handler, each 4K RAM disk bank 6043 ; contains 21 pages of 128 twelve bit words, packed using the standard OS/8 6044 ; "three for two" scheme. A 512K SRAM chip can hold 128 of these banks, 6045 ; corresponding to DAR addresses 0..127, for a total capacity of 2688 PDP-8 6046 ; pages or 1344 OS/8 blocks. A 128K SRAM would contain only 32 banks, for a 6047 ; total of 672 PDP-8 pages or 336 OS/8 blocks. 6048 ; 6049 ; Sixty-four bytes are wasted in each bank by this packing scheme, which 6050 ; works out to about 21 OS/8 blocks lost in a 512K SRAM. More clever software 6051 ; could reclaim these, but it would require that the three-for-two packing 6052 ; algorithm split PDP-8 pages across RAM disk banks. 6053 ; 6054 ; The SRAMs are optional, and this SBC6120 may have all, only some, or even 6055 ; none installed. Since each SRAM chip is treated as a separate OS/8 unit, 6056 ; this makes it easy to handle the situation where some chips are not missing - 6057 ; these units are simply "off line". 6058 6059 ; RAM disk "geometry" constants... 6060 5200 RAM512=2688. ; size of a 512K RAM disk, in pages 6061 1240 RAM128=672. ; " " " 128K " " " " 6062 0025 BANKSZ=21. ; pages per bank of RAM disk memory 6063 6064 ; Special IOTs for the RAM disk hardware... 6065 6410 LDAR=6410 ; Load RAM disk address register 6066 6415 SBBLO=6415 ; Skip on backup battery low (DS1321 only!) PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 146 RAM Disk Read/Write ROM Call BTS6120.plx 6067 .TITLE RAM Disk Read/Write ROM Call 6068 6069 6070 ; The calling sequence for the PR0 RAM disk R/W function is: 6071 ; 6072 ; PR0 6073 ; 0001 / panel function code for RAMDISK I/O 6074 ; / R/W bit, page count, buffer field and unit 6075 ; / buffer address 6076 ; / starting page number (not block number!) 6077 ; / AC == 0 if success; AC != 0 if error 6078 ; 6079 ; The error codes currently returned by RAMDRW are: 6080 ; 6081 ; 0001 - unit > 3 or SRAM chip not installed 6082 ; 0002 - page number > 2688 6083 ; 6084 ; If this looks a lot like an OS/8 handler call, that's no accident! 6085 10310 6205 RAMDRW: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 10311 5765 6086 10312 6205 .PUSHJ GETARG ; and lastly get the disk page number 10313 5241 6087 10314 3025 DCA RDPAGE ; ... 6088 6089 ; Select (after first ensuring that it exists!) the correct unit... 6090 10315 1047 TAD MUUO ; next get the unit number 6091 10316 0364 AND [7] ; ... 6092 10317 3024 DCA RDUNIT ; ... 6093 10320 6205 .PUSHJ @[RAMSEL] ; setup RAMCDF to select the correct "unit" 10321 5763 6094 10322 7630 SZL CLA ; was the unit number illegal ? 6095 10323 5762 JMP @[RAMER1] ; yes - give the error return 6096 6097 ; This loop reads or writes pages 'till we've done all we're supposed to... 6098 10324 6205 RDRW1: .PUSHJ @[SETDAR] ; calculate the RAM disk address and bank 10325 5761 6099 10326 7630 SZL CLA ; was the page number valid? 6100 10327 5760 JMP @[RAMER2] ; nope - give the bad page error return 6101 10330 1047 TAD MUUO ; get the function code again 6102 10331 7700 SMA CLA ; should we read (0) or write (1) ? 6103 10332 5336 JMP RDRW2 ; ... read 6104 10333 6205 .PUSHJ @[PACK] ; transfer a page from memory to RAM disk 10334 5757 6105 10335 5340 JMP RDRW3 ; and continue 6106 10336 6205 RDRW2: .PUSHJ @[UNPACK] ; transfer a page from RAM disk to memory 10337 5756 6107 10340 2025 RDRW3: ISZ RDPAGE ; if we need more, continue on the next page 6108 10341 2054 ISZ RWCNT ; have we done enough pages? 6109 10342 5324 JMP RDRW1 ; nope - keep going 6110 10343 7200 CLA ; all done with the RAMDRW call 6111 10344 6225 .POPJ ; return status code zero (no error) 6112 10356 0436 10357 0500 10360 0433 10361 0654 10362 0431 10363 0713 10364 0007 10365 2123 10366 0271 10367 6201 10370 0070 10371 0000 10372 7707 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 147 RAM Disk Read/Write ROM Call BTS6120.plx 10373 2225 10374 0002 10375 0001 10376 0261 10377 7756 6113 10400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 148 RAM Disk Primary Bootstrap BTS6120.plx 6114 .TITLE RAM Disk Primary Bootstrap 6115 6116 ; This routine will read page zero from RAM disk unit zero into page 6117 ; zero of field zero of main memory. The next step in the usual boot 6118 ; sequence would be to start the secondary bootstrap, but that's up to 6119 ; the caller... 6120 10400 7240 RDBOOT: STA ; point the buffer to page 0 6121 10401 3011 DCA BUFPTR ; ... 6122 10402 1377 TAD [CDF 0] ; of field zero 6123 10403 3776 DCA @[BUFCDF+1] ; ... 6124 10404 3052 DCA BUFPNL ; of main memory 6125 10405 3024 DCA RDUNIT ; read RAM disk unit zero 6126 10406 3025 DCA RDPAGE ; page zero 6127 ; JMP RAMDRD ; ... 6128 ; ** fall through into RAMDRD *** 6129 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 149 Read and Write RAM Disk Pages BTS6120.plx 6130 .TITLE Read and Write RAM Disk Pages 6131 6132 6133 ; This routine will read a single page from RAM disk to a buffer in memory. 6134 ; The caller must set up RDUNIT and RDPAGE with the desired RAM disk unit 6135 ; and page, and BUFPTR, BUFCDF and BUFPNL with the address of a 128 word 6136 ; buffer in 6120 memory. If any errors are encountered, this routine will 6137 ; return with the LINK set and an error status in the AC. 6138 10407 6205 RAMDRD: .PUSHJ @[RAMSEL] ; select the unit in RDUNIT 10410 5775 6139 10411 7430 SZL ; was it invalid?? 6140 10412 5231 JMP RAMER1 ; yes - return error code 1 6141 10413 6205 .PUSHJ @[SETDAR] ; calculate the necessary disk address 10414 5774 6142 10415 7430 SZL ; is the page number invalid? 6143 10416 5233 JMP RAMER2 ; yes - return error code 2 6144 10417 5773 JMP @[UNPACK] ; unpack RAM disk data to the buffer and return 6145 6146 6147 ; This routine will write a single page from 6120 memory to RAM disk. Except 6148 ; for the direction of data flow, it's identical to RAMDRD, including all the 6149 ; parameters and error returns. 6150 10420 6205 RAMDWR: .PUSHJ @[RAMSEL] ; select the unit 10421 5775 6151 10422 7430 SZL ; was it invalid?? 6152 10423 5231 JMP RAMER1 ; yes - return error code 1 6153 10424 6205 .PUSHJ @[SETDAR] ; calculate the disk address 10425 5774 6154 10426 7430 SZL ; invalid page number?? 6155 10427 5233 JMP RAMER2 ; yes - return error code 2 6156 10430 5772 JMP @[PACK] ; pack buffer data into the RAM disk and return 6157 6158 6159 ; Here if the unit number is invalid... 6160 10431 7321 RAMER1: CLA CLL CML IAC ; return LINK = 1 and AC = 1 6161 10432 6225 .POPJ ; ... 6162 6163 ; Here if the page number is invalid... 6164 10433 7326 RAMER2: NL0002 ; return AC = 2 6165 10434 7120 STL ; and LINK = 1 6166 10435 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 150 Unpack RAM Disk Pages BTS6120.plx 6167 .TITLE Unpack RAM Disk Pages 6168 6169 6170 ; This routine will read one page (aka a sector) of 128 PDP-8 words from 6171 ; the RAM disk to a buffer anywhere in main memory or panel memory. The 6172 ; address of the disk page read is selected by the RAMCDF and RAMPTR locations 6173 ; and the DAR register, which should be set up by prior calls to the RAMUNIT 6174 ; and SETDAR routines. The address of the buffer written is selected by the 6175 ; BUFPTR, BUFCDF and BUFPNL locations, which must be set up by the caller 6176 ; before invoking this routine. Exactly 128 words are always transferred, 6177 ; without fail! 6178 10436 7200 UNPACK: CLA ; ... 6179 10437 1371 TAD [-64.] ; one page is 128 words, or 64 word pairs 6180 10440 3051 DCA XFRCNT ; ... 6181 6182 ; Fetch the next three bytes (two words) from the SRAM chip. Note that 6183 ; the SRAMs are only eight bits wide, so we'll read indeterminate garbage for 6184 ; the upper four bits of each word. Those have to be masked off on the first 6185 ; two bytes, but for the third one it doesn't matter - it gets masked to two 6186 ; four bit pieces later anyway... 6187 10441 4770 UNPAC1: JMS @[RAMCDF] ; change the DF to the RAM disk unit 6188 10442 6403 MM3 ; and enable the RAM disk chips 6189 10443 1410 TAD @RAMPTR ; fetch three bytes from RAM disk 6190 10444 0367 AND [377] ; eight bits only, please 6191 10445 3026 DCA RAMBUF ; ... 6192 10446 1410 TAD @RAMPTR ; ... 6193 10447 0367 AND [377] ; ... 6194 10450 3027 DCA RAMBUF+1 ; ... 6195 10451 1410 TAD @RAMPTR ; ... 6196 10452 3030 DCA RAMBUF+2 ; ... 6197 10453 6402 MM2 ; restore the default memory map 6198 10454 6211 CDF 1 ; and field 6199 6200 ; Pack the three bytes into two words and store them in main/panel memory... 6201 10455 4766 JMS @[BUFCDF] ; change DF to the buffer field 6202 10456 1030 TAD RAMBUF+2 ; the upper 4 bits of the first word are here 6203 10457 7002 BSW ; shift them left six 6204 10460 7106 CLL RTL ; ... then eight bits 6205 10461 0365 AND [7400] ; and isolate just those four bits 6206 10462 1026 TAD RAMBUF ; assemble the first word 6207 10463 3411 DCA @BUFPTR ; and store it in main memory 6208 10464 1030 TAD RAMBUF+2 ; now do the upper 4 bits of the second word 6209 10465 7106 CLL RTL ; shift them left two 6210 10466 7106 CLL RTL ; ... then four bits 6211 10467 0365 AND [7400] ; and isolate just those four bits 6212 10470 1027 TAD RAMBUF+1 ; reassemble the second word 6213 10471 3411 DCA @BUFPTR ; store that in main memory too 6214 10472 6276 SPD ; return to panel memory 6215 10473 6211 CDF 1 ; and our own memory field 6216 10474 2051 ISZ XFRCNT ; have we done a full page? 6217 10475 5241 JMP UNPAC1 ; nope - keep copying 6218 10476 7100 CLL ; be sure the LINK is cleared for success 6219 10477 6225 .POPJ ; yes - we're outta here! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 151 Pack RAM Disk Pages BTS6120.plx 6220 .TITLE Pack RAM Disk Pages 6221 6222 6223 ; This routine will write one page of 128 PDP-8 words from a buffer anywhere 6224 ; in either panel or main memory to RAM disk. It's the exact complement of 6225 ; UNPACK, and expects exactly the same things to be set up. 6226 10500 7200 PACK: CLA ; don't assume anything! 6227 10501 1371 TAD [-64.] ; do 64 word pairs, or 128 words 6228 10502 3051 DCA XFRCNT ; ... 6229 6230 ; Grab the next two twelve bit words from the buffer... 6231 10503 4766 PACK1: JMS @[BUFCDF] ; change DF to the buffer's field 6232 10504 1411 TAD @BUFPTR ; get a word from the buffer 6233 10505 3026 DCA RAMBUF ; save it for the computation of byte 3 6234 10506 1411 TAD @BUFPTR ; do the same with the second word 6235 10507 3027 DCA RAMBUF+1 ; ... 6236 10510 6276 SPD ; back to panel memory addressing 6237 6238 ; Store bytes 1 and 2 (they're easy) and calculate byte three. Note that 6239 ; the SRAM will ignore the upper four bits when writing (there's no hardware 6240 ; there!) so there's no need to worry about masking them out first... 6241 10511 4770 JMS @[RAMCDF] ; select the correct SRAM "unit" 6242 10512 6403 MM3 ; and enable the SRAM chips 6243 10513 1026 TAD RAMBUF ; store byte 1 6244 10514 3410 DCA @RAMPTR ; ... 6245 10515 1027 TAD RAMBUF+1 ; and byte 2 6246 10516 3410 DCA @RAMPTR ; ... 6247 10517 1026 TAD RAMBUF ; byte 3 has the top four bits of word 1 6248 10520 0365 AND [7400] ; ... 6249 10521 7002 BSW ; ... in bits 8..11 of the byte 6250 10522 7112 CLL RTR ; ... 6251 10523 3026 DCA RAMBUF ; save that for a moment 6252 10524 1027 TAD RAMBUF+1 ; and the top four bits of word 2 6253 10525 0365 AND [7400] ; ... 6254 10526 7112 CLL RTR ; in bits 4..7 6255 10527 7112 CLL RTR ; ... 6256 10530 1026 TAD RAMBUF ; ... 6257 10531 3410 DCA @RAMPTR ; ... 6258 10532 6402 MM2 ; return to the default memory map 6259 10533 6211 CDF 1 ; and field 6260 10534 2051 ISZ XFRCNT ; have we done a whole page? 6261 10535 5303 JMP PACK1 ; nope - keep going 6262 10536 7100 CLL ; be sure the LINK is cleared for success 6263 10537 6225 .POPJ ; all done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 152 Test DS1221 Batteries BTS6120.plx 6264 .TITLE Test DS1221 Batteries 6265 6266 6267 ; This routine will test the status of the RAM disk backup batteries on the 6268 ; original, DS1221, RAM disk card. This routine will return incorrect, but 6269 ; harmless, information if the system really has the newer DS1231 RAM disk or 6270 ; the IOB6120 RAM disk, or no RAM disk at all. 6271 ; 6272 ; The DS1221 doesn't have a status bit to give us the battery state directly, 6273 ; but it does have a clever hack to allow us to infer what we want to know. If 6274 ; the batteries have failed, then the DS1221 will inhibit all chip select 6275 ; outputs on the _second_ memory cycle (but not the first!). We can use this 6276 ; by 1) reading any location and saving its value, 2) writing any different 6277 ; value to the same location, and 3) reading it back again. If the batteries 6278 ; are dead, the second cycle will be inhibited, and the value read in step 3 6279 ; will be the same as 1. Of course, this presupposes that there's functional 6280 ; memory installed in the first place, if there isn't then this algorithm will 6281 ; erroneously report that the batteries are dead. 6282 ; 6283 ; Because of the way this works, this routine has to be called before ANY 6284 ; other access is made to MM3, including the extension ROM initialization. 6285 ; That's why the DS1221 battery test is in a routine all by itself - the 6286 ; battery test for the other two styles (DS1231 and IOB6120) is done by the 6287 ; RDCHK1 routine. 6288 ; 6289 10540 0000 CK1221: 0 6290 10541 1364 TAD [32.] ; test bank 32 to avoid A17 problem 6291 10542 6410 LDAR ; select the RAM bank for testing 6292 10543 6403 MM3 ; enable RAM disk access 6293 10544 6201 CDF 0 ; use 1st RAMdisk RAM for test 6294 10545 1763 TAD @[7777] ; (1) read the last byte of this bank 6295 10546 7421 MQL ; save it for a minute 6296 10547 7701 ACL ; .... 6297 10550 7041 CIA ; make it negative 6298 10551 3763 DCA @[7777] ; (2) and write it back 6299 10552 7701 ACL ; get the original data 6300 10553 1763 TAD @[7777] ; (3) add what should be the complement 6301 10554 0367 AND [377] ; ignore all but the bottom eight bits 6302 10555 7650 SNA CLA ; if it's not zero then the second cycle was 6303 10556 7344 NLM2 ; ... inhibited because the batteries are dead 6304 10557 7001 IAC ; AC=-1 if battery good, AC=+1 if battery bad 6305 10560 3032 DCA BATTOK ; ..... 6306 ; CDF 1 ; back to current field 6307 10561 6402 MM2 ; back to the default memory map 6308 10562 5740 JMP @CK1221 ; ... 6309 10563 7777 10564 0040 10565 7400 10566 2211 10567 0377 10570 0744 10571 7700 10572 0500 10573 0436 10574 0654 10575 0713 10576 2212 10577 6201 6310 10600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 153 Get Battery Status ROM Call BTS6120.plx 6311 .TITLE Get Battery Status ROM Call 6312 6313 6314 ; The Get Battery Status ROM call will return the status of the RAM disk 6315 ; lithium backup batteries. As long as either battery has sufficient 6316 ; voltage, -1 will be return in the AC. If both batteries have failed, then 6317 ; zero is returned. 6318 ; 6319 ; PR0 / call the SBC6120 ROM firmware 6320 ; 0003 / get backup battery status function code 6321 ; / return with AC == -1 if batteries are OK 6322 ; / AC == +1 if batteries are bad 6323 ; / AC == 0 if battery status unknown 6324 ; 6325 ; NOTE: Because of the way the DS1221 works, the battery status can only 6326 ; be tested after power up. It isn't possible to monitor the battery status 6327 ; in real time! 6328 10600 7300 GETBAT: CLA CLL ; ... 6329 10601 1032 TAD BATTOK ; return the battery status in the AC 6330 10602 6225 .POPJ ; and that's it PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 154 Determine RAM Disk Model BTS6120.plx 6331 .TITLE Determine RAM Disk Model 6332 6333 ; This routine will determine the type of the RAM disk installed and sets 6334 ; the RDTYPE variable accordingly: 6335 ; 6336 ; -2 -> IOB6120 RAM disk 6337 ; -1 -> original (DS1221) RAM disk 6338 ; 0 -> no RAM disk 6339 ; +1 -> new (DS1231) RAM disk 6340 ; 6341 ; Each of these implementations has slightly different characteristics (sigh!) 6342 ; and so it's important to know which one we've got. Note that this routine 6343 ; is called only once, during phase 2 of system initialization. 6344 10603 7200 RDCHK1: CLA 6345 ; If the IOB6120 is in use, then we've obviously got the IOB6120 style 6346 ; RAM disk. Also, since the IOB6120 doesn't support any low battery detection 6347 ; for the RAM disk backup battery, we'll take this chance to set BATTOK to 6348 ; zero (unknown battery status). 6349 10604 6201 CDF 0 ; the EXTFLAG lives in field 0 6350 10605 1777 TAD @[EXTFLAG] ; get the IOB6120 status 6351 10606 6211 CDF 1 ; ... 6352 10607 7650 SNA CLA ; is there one? 6353 10610 5214 JMP RDCH10 ; no - go check for a DS1221 RAMdisk card 6354 10611 3032 DCA BATTOK ; yes - set the battery status to unknown 6355 10612 7344 NLM2 ; and set RDTYPE to -2 (IOB6120 RAM disk) 6356 10613 5251 JMP RDCH12 ; .... 6357 6358 ; The original RAMdisk card (the one with the DS1221 chip) didn't decode 6359 ; EMA2 and so the even and odd fields select the same SRAM chip. This code 6360 ; does a very simple test to detect that case (remember that we aren't even 6361 ; sure _any_ RAMdisk exists at this point!) and sets the maximum unit to 4 6362 ; if it detects this duplication. Note that this assumes that if any 6363 ; RAMdisk chip is installed, the first one is! 6364 10614 1376 RDCH10: TAD [32.] ; test bank 32 so A17 will be set 6365 10615 6410 LDAR ; ... 6366 10616 6403 MM3 ; address the RAMdisk map 6367 10617 6201 CDF 0 ; select the first chip 6368 10620 1375 TAD [252] ; put a test pattern in one location 6369 10621 3774 DCA @[7776] ; ... 6370 10622 1373 TAD [125] ; and a different one in the next 6371 10623 3772 DCA @[7777] ; ... 6372 10624 1774 TAD @[7776] ; add them up 6373 10625 1772 TAD @[7777] ; ... 6374 10626 7040 CMA ; the result should be 377 6375 10627 0371 AND [377] ; remember that only 8 bits exist 6376 10630 7640 SZA CLA ; skip if any RAM disk exists? 6377 10631 5251 JMP RDCH12 ; none - set RDTYPE to zero and exit 6378 10632 6211 CDF 1 ; address an odd numbered chip 6379 10633 3774 DCA @[7776] ; clear this location in chip #1 6380 10634 6201 CDF 0 ; read the original chip again 6381 10635 1774 TAD @[7776] ; ... 6382 10636 0371 AND [377] ; the RAMdisk array is only 8 bits 6383 10637 1370 TAD [-252] ; if this is now zero 6384 10640 7650 SNA CLA ; ... we can be pretty sure it's an old card 6385 10641 5244 JMP RDCH11 ; nope - modern DS1231 card 6386 6387 ; Here for the old stype (DS1221) card... 6388 10642 7240 NLM1 ; set RDTYPE to -1 6389 10643 5251 JMP RDCH12 ; store it and return... 6390 6391 ; Here for a modern (DS1231) card... 6392 10644 7201 RDCH11: NL0001 ; set the AC to +1 6393 10645 6415 SBBLO ; skip of the DS1231 battery is low 6394 10646 7240 NLM1 ; not low - set BATTOK to -1 6395 10647 3032 DCA BATTOK ; update the battery status flag PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 155 Determine RAM Disk Model BTS6120.plx 6396 10650 7201 NL0001 ; and finally set RDTYPE to 1 6397 10651 3046 RDCH12: DCA RDTYPE ; ... 6398 10652 6402 MM2 ; return to the normal memory map 6399 10653 6225 .POPJ ; and we're all done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 156 Calculate RAM Disk Addresses BTS6120.plx 6400 .TITLE Calculate RAM Disk Addresses 6401 6402 6403 ; This routine will calculate the RAM disk bank number and the relative 6404 ; offset within that bank, corresponding to a disk page number passed in 6405 ; location DKPAGE. The resulting bank number is simply loaded directly into 6406 ; the DAR via the LDAR IOT, and the offset is left in auto index location 6407 ; RAMPTR, where it can be used by the UNPACK and PACK routines. If the page 6408 ; number passed is illegal (i.e. greater than the size of the selected RAM 6409 ; disk unit) then the link will be set when this routine returns. 6410 10654 7300 SETDAR: CLA CLL ; make sure the link is in a known state 6411 10655 1025 TAD RDPAGE ; get the desired page 6412 10656 1045 TAD RAMUSZ ; compare it to the size of this unit 6413 10657 7630 SZL CLA ; is the page number legal? 6414 10660 6225 .POPJ ; no - return with the LINK set 6415 6416 ; Divide the page number by 21, the number of pages per bank, by repeated 6417 ; subtraction. This is kind of crude, but it only has to iterate 127 times, 6418 ; worst case, so the performance hit isn't that bad. We do have to be careful, 6419 ; though, because the largest legal page number is 2688, which is bigger than 6420 ; 2048. That means we have to treat the whole AC as a 12 bit UNSIGNED value! 6421 10661 3031 DCA RAMDAR ; clear the disk address (quotient) 6422 10662 1025 TAD RDPAGE ; get the selected RAM disk page number 6423 10663 7100 SETDA1: CLL ; make sure the link is clear before starting 6424 10664 1367 TAD [-BANKSZ] ; try to subtract another 21 6425 10665 7420 SNL ; did it fit? 6426 10666 5271 JMP SETDA2 ; nope - we can stop now 6427 10667 2031 ISZ RAMDAR ; yes - increment the disk address 6428 10670 5263 JMP SETDA1 ; and keep subtracting 6429 6430 ; We get here when we're done dividing, with the quotient in RAMDAR and the 6431 ; remainder in the AC. To calculate the byte offset within a bank, we need 6432 ; to multiply the remainder by 192 (the number of bytes per 128 word page). 6433 10671 1366 SETDA2: TAD [BANKSZ] ; restore the remainder 6434 10672 7002 BSW ; then multiply by 64 6435 10673 3010 DCA RAMPTR ; save offset*64 for a moment 6436 10674 1010 TAD RAMPTR ; ... 6437 10675 7104 CLL RAL ; then multiply by two again 6438 10676 1010 TAD RAMPTR ; 192*x = 128*x + 64*x 6439 10677 6201 CDF 0 ; adjust by base offset, default 0 - 1 6440 10700 1765 TAD @[RAMBAS] ; (auto index registers pre-increment) 6441 10701 6211 CDF 1 6442 10702 3010 DCA RAMPTR ; that's the final offset 6443 6444 ; Set up the DAR with the bank number, from RAMDAR. Remember that for the 6445 ; 128K chips, we must always set A17 to enable the alternate chip select! 6446 10703 1045 TAD RAMUSZ ; get the size of the selected unit 6447 10704 1364 TAD [RAM128] ; ... 6448 10705 7650 SNA CLA ; is this a 128K ram chip ? 6449 10706 1376 TAD [32.] ; yes - always set A17 6450 10707 1031 TAD RAMDAR ; get the quotient from the division 6451 10710 6410 LDAR ; and load the disk address register 6452 10711 7100 CLL ; indicate success 6453 10712 6225 .POPJ ; and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 157 Select RAM Disk Unit BTS6120.plx 6454 .TITLE Select RAM Disk Unit 6455 6456 6457 ; This routine will set up the RAMCDF routine to select the desired RAM 6458 ; disk "unit". The unit number, 0..7, should be passed in RDUNIT. If the 6459 ; unit number given is illegal (i.e. greater than seven) OR if there is no 6460 ; SRAM chip installed in the selected position, this routine will return 6461 ; with the link set. 6462 10713 7300 RAMSEL: CLL CLA ; make sure the link is in a known state 6463 10714 1024 TAD RDUNIT ; get the desired unit number 6464 10715 1363 TAD [-10] ; see if the unit is legal 6465 10716 7630 SZL CLA ; it must be less than 8 6466 10717 6225 .POPJ ; no - return with the link set 6467 ; The mapping of RAMdisk units to data fields is a little obscure - units 6468 ; 0..3 map to fields 0, 2, 4, and 6 (i.e. the even fields). RAMdisk units 6469 ; 4..7 map to the odd fields (1, 3, 5, 7)... 6470 10720 1024 TAD RDUNIT ; restore the original unit 6471 10721 7104 CLL RAL ; shift the unit number left once 6472 10722 1363 TAD [7770] ; if the unit is 4..7 then set the link 6473 10723 7430 SZL ; skip if the unit is 0..3 6474 10724 7001 IAC ; make the field odd for units 4..7 6475 10725 7114 CLL R3L ; and position it for a CDF instruction 6476 10726 0362 AND [70] ; ... 6477 10727 1361 TAD [CDF 0] ; make a CDF to the corresponding field 6478 10730 3345 DCA RAMCDF+1 ; and store that in the unit select routine 6479 6480 ; Now that we know the unit number is valid, verify that this chip is really 6481 ; installed by checking the RDSIZE array for a non-zero value. As a side 6482 ; effect of this, we always leave the size of the currently selected unit in 6483 ; location RAMUSZ, where it's used by SETDAR to determine whether the page 6484 ; addressed is actually legal. We always want to update RAMUSZ, even if the 6485 ; chip is not installed, because this will also cause SETDAR to fail if the 6486 ; caller ignores the our error return and attempts a read or write anyway. 6487 10731 1024 TAD RDUNIT ; get the unit number again 6488 10732 1377 TAD [RDSIZE] ; index into the RDSIZE array 6489 10733 3044 DCA SIZPTR ; ... 6490 10734 1444 TAD @SIZPTR ; to get the size of this chip 6491 10735 7041 CIA ; make it negative 6492 10736 3045 DCA RAMUSZ ; and save that for SETDAR 6493 10737 1045 TAD RAMUSZ ; ... 6494 10740 7100 CLL ; make sure the link is in a known state 6495 10741 7650 SNA CLA ; is this chip installed ? 6496 10742 7020 CML ; nope - give the error return 6497 10743 6225 .POPJ ; ... 6498 6499 ; This little routine can be called, via a JMS instruction (not a .PUSHJ!) 6500 ; to change the DF and select the last RAM disk unit set by a call to RAMSEL. 6501 10744 0000 RAMCDF: 0 ; call here via a JMS! 6502 10745 7000 NOP ; gets overwritten with a CDF instruction 6503 10746 5744 JMP @RAMCDF ; return... 6504 10761 6201 10762 0070 10763 7770 10764 1240 10765 0034 10766 0025 10767 7753 10770 7526 10771 0377 10772 7777 10773 0125 10774 7776 10775 0252 10776 0040 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 158 Select RAM Disk Unit BTS6120.plx 10777 0033 6505 11000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 159 Get RAM Disk Size ROM Call BTS6120.plx 6506 .TITLE Get RAM Disk Size ROM Call 6507 6508 6509 ; PR0 function 2 will return the size of a RAM disk chip, in 128 word pages, 6510 ; in the AC. The AC should be loaded with the desired unit number, 0..7, 6511 ; before invoking PD0. If no chip is installed in the selected unit, zero 6512 ; will be returned in the AC. If the unit number is not in the range 0..7, 6513 ; then on return the LINK will be set to indicate an error. 6514 ; 6515 ; For example: 6516 ; TAD (unit / load the desired RAM disk unit, 0..7 6517 ; PR0 / call the ROM software 6518 ; 0002 / function code for Get RAM Disk Status 6519 ; / return the RAM disk size in the AC 6520 6521 ; It's tempting to use the RAMSEL routine here to save some steps, but be 6522 ; careful - RAMSEL will return with the LINK set (an error condition) if a 6523 ; valid unit number is selected but there is no SRAM chip installed there. 6524 ; That's not what we want for this ROM call, which should return an error only 6525 ; if the selected unit is > 7! 6526 11000 3024 GETRDS: DCA RDUNIT ; save the unit number 6527 11001 1024 TAD RDUNIT ; and get it back 6528 11002 7100 CLL ; be sure the link is in a known state 6529 11003 1377 TAD [-10] ; is it a legal unit number ? 6530 11004 7630 SZL CLA ; skip if so 6531 11005 6225 .POPJ ; no - return with the LINK set and AC clear 6532 11006 1024 TAD RDUNIT ; one more time 6533 11007 1376 TAD [RDSIZE] ; index the RDSIZE array 6534 11010 3044 DCA SIZPTR ; ... 6535 11011 1444 TAD @SIZPTR ; get the size of this disk 6536 11012 6225 .POPJ ; and return it with the LINK cleared PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 160 ATA Disk Support BTS6120.plx 6537 .TITLE ATA Disk Support 6538 6539 6540 ; BTS6120 supports any standard ATA hard disk connected to the SBC6120 IDE 6541 ; interface. Nearly all hard disks with IDE interfaces are ATA; conversely, 6542 ; nearly all non-hard disk devices (e.g. CDROMs, ZIP drives, LS-120s, etc) 6543 ; with IDE interfaces are actually ATAPI and not ATA. ATAPI requires a 6544 ; completely different protocol, which BTS6120 does not support, and BTS6120 6545 ; will simply ignore any ATAPI devices connected to the IDE interface. 6546 ; BTS6120 supports only a single physical drive, which must be set up as the 6547 ; IDE master, and any IDE slave device will be ignored. 6548 ; 6549 ; Since BTS6120 does not support cylinder/head/sector (C/H/S) addressing, 6550 ; the hard disk used must support logical block addressing (LBA) instead. 6551 ; All modern IDE/ATA drives support LBA, as do most drives manufactured in the 6552 ; last five or six years, however some very old drives may not. If BTS6120 6553 ; detects an ATA drive that does not support LBA it will display the message 6554 ; "IDE: Not supported" during startup and there after ignore the drive. 6555 ; 6556 ; All IDE devices, regardless of vintage, transfer data in sixteen bit words 6557 ; and each sector on an ATA disk contains 512 bytes, or 256 sixteen bit words. 6558 ; When writing to the disk, BTS6120 converts twelve bit PDP-8 words to sixteen 6559 ; bits by adding four extra zero bits to the left and, when reading from the 6560 ; disk, BTS6120 converts sixteen bit words to twelve bits by simply discarding 6561 ; the most significant four bits. No packing is done. This conveniently 6562 ; means that each ATA sector holds 256 PDP-8 words, or exactly one OS/8 block. 6563 ; It also means that one quarter of the disk space is wasted, in this era of 6564 ; multi-gigabyte disks that hardly seems like an issue. 6565 ; 6566 ; OS/8 handlers and the OS/8 file system use a single twelve bit word to hold 6567 ; block numbers, which means that OS/8 mass storage devices are limited to a 6568 ; maximum of 4096 blocks . Using the BTS6120 non-packing scheme for storing 6569 ; data, 4096 PDP-8 blocks are exactly 2Mb. Clearly, if a single OS/8 device 6570 ; corresponds to an entire hard disk then nearly all of the disk space would 6571 ; be wasted. The normal solution is to partition the hard disk into many OS/8 6572 ; units, with each unit representing only a part of the entire disk. Since 6573 ; OS/8 cannot support a single unit larger than 2Mb there isn't any point in 6574 ; allowing partitions to be larger than that, and since the smallest drives 6575 ; available today can hold hundreds if not thousands of 2Mb partitions, there 6576 ; isn't much point in allowing a partition to be smaller than that, either. 6577 ; 6578 ; Because of this, BTS6120 supports only fixed size partitions of 2Mb each. 6579 ; This greatly simplifies the software since a twenty four bit disk sector 6580 ; number can now be calculated simply by concatenating a twelve bit partition 6581 ; number with the twelve bit OS/8 relative block number (RBN). No "super 6582 ; block" with a partition table is needed to keep track of the sizes and 6583 ; positions of each partition, and the OS/8 handler is simplified since each 6584 ; disk partition is always the same size. A twenty four bit sector address 6585 ; permits disks of up to 8Gb to be fully used, which seems more than enough 6586 ; for a PDP-8. 6587 ; 6588 ; Once again, in BTS6120 the partition number simply refers to the most 6589 ; significant twelve bits of a twenty-four bit disk address, and the OS/8 6590 ; block number is the least significant twelve bits. It's no more complicated 6591 ; than that! 6592 ; 6593 ; The ID01 is the OS/8 handler for the SBC6120 IDE/ATA disk. It supports 6594 ; eight units, IDA0 through IDA7, in a single page and may be assembled as 6595 ; either a system (IDSY) or non-system (IDNS) handler. The system handler 6596 ; version of the ID01 contains a secondary bootstrap that can be booted by 6597 ; the BTS6120 Boot command. The ID01 is a simple handler that uses HD-6120 6598 ; PR0 instruction to invoke BTS6120 functions for low level IDE disk access 6599 ; and data transfer. 6600 ; 6601 ; BTS6120 implements a partition map which defines the partition number PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 161 ATA Disk Support BTS6120.plx 6602 ; corresponding to each OS/8 ID01 unit, and when an OS/8 program accesses an 6603 ; ID01 unit BTS6120 uses this table to determine the upper twelve bits of the 6604 ; LBA. At power on or after a MR command, BTS6120 initializes this partition 6605 ; map so that unit 0 accesses partition 0, unit 1 accesses partition 1, and 6606 ; so on up through unit 7 and partition 7. This mapping remains in effect 6607 ; until it is changed by either the PM command, or the Set IDE Disk Partition 6608 ; Mapping PR0 function. 6609 ; 6610 ; The largest mass storage device supported by OS/8 is actually only 4095 6611 ; blocks, not 4096, and so the last block of every 2Mb partition is never 6612 ; used by OS/8. This block can, however, be accessed via the Read/Write IDE 6613 ; disk PR0 function (section 6.5), and it can be used to store the name, 6614 ; creation date, and other information about that partition. The OS/8 PART 6615 ; program uses this to allow partitions to be mounted on ID01 logical units 6616 ; by name rather than partition number. Named partitions are strictly a 6617 ; function of the OS/8 PART program and BTS6120 knows nothing about them. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 162 IDE Disk Interface BTS6120.plx 6618 .TITLE IDE Disk Interface 6619 6620 6621 ; In the SBC6120, the IDE interface is implemented via a standard 8255 PPI, 6622 ; which gives us 24 bits of general purpose parallel I/O. Port A is connected 6623 ; the high byte (DD8..DD15) of the IDE data bus and port B is connected to 6624 ; the low byte (DD0..DD7). Port C supplies the IDE control signals as follow: 6625 ; 6626 ; C0..C2 -> DA0 .. 2 (i.e. device address select) 6627 ; C.3* -> DIOR L (I/O read) 6628 ; C.4* -> DIOW L (I/O write) 6629 ; C.5* -> RESET L 6630 ; C.6* -> CS1Fx L (chip select for the 1Fx register space) 6631 ; C.7* -> CS3Fx L ( " " " " 3Fx " " ) 6632 ; 6633 ; * These active low signals (CS1Fx, CS3Fx, DIOR, and DIOW) are inverted in 6634 ; the hardware so that writing a 1 bit to the register asserts the signal. 6635 ; 6636 ; One nice feature of the 8255 is that it allows bits in port C to be 6637 ; individually set or reset simply by writing the correct command word to the 6638 ; control register - it's not necessary to read the port, do an AND or OR, 6639 ; and write it back. We can use this feature to easily toggle the DIOR and 6640 ; DIOW lines with a single PWCR IOT. 6641 0222 IDEINP=222 ; set ports A and B as inputs, C as output 6642 0200 IDEOUT=200 ; set ports A and B (and C too) as outputs 6643 0007 SETDRD=007 ; assert DIOR L (PC.3) in the IDE interface 6644 0006 CLRDRD=006 ; clear " " " " " " " " 6645 0011 SETDWR=011 ; assert DIOW L (PC.4) in the IDE interface 6646 0010 CLRDWR=010 ; clear " " " " " " " " 6647 0013 SETDRE=013 ; assert DRESET L (PC.5) in the IDE interface 6648 0012 CLRDRE=012 ; clear " " " " " " " " 6649 6650 ; Standard IDE registers... 6651 ; (Note that these are five bit addresses that include the two IDE CS bits, 6652 ; CS3Fx (AC4) and CS1Fx (AC5). The three IDE register address bits, DA2..DA0 6653 ; correspond to AC9..AC11. 6654 0100 CS1FX=100 ; PC.6 selects the 1Fx register space 6655 0200 CS3FX=200 ; PC.7 " " 3Fx " " " 6656 0100 REGDAT=CS1FX+0 ; data (R/W) 6657 0101 REGERR=CS1FX+1 ; error (R/O) 6658 0102 REGCNT=CS1FX+2 ; sector count (R;W) 6659 0103 REGLB0=CS1FX+3 ; LBA byte 0 (or sector number) R/W 6660 0104 REGLB1=CS1FX+4 ; LBA byte 1 (or cylinder low) R/W 6661 0105 REGLB2=CS1FX+5 ; LBA byte 2 (or cylinder high) R/W 6662 0106 REGLB3=CS1FX+6 ; LBA byte 3 (or device/head) R/W 6663 0107 REGSTS=CS1FX+7 ; status (R/O) 6664 0107 REGCMD=CS1FX+7 ; command (W/O) 6665 6666 ; IDE status register (REGSTS) bits... 6667 0200 STSBSY=0200 ; busy 6668 0100 STSRDY=0100 ; device ready 6669 0040 STSDF= 0040 ; device fault 6670 0020 STSDSC=0020 ; device seek complete 6671 0010 STSDRQ=0010 ; data request 6672 0004 STSCOR=0004 ; corrected data flag 6673 0001 STSERR=0001 ; error detected 6674 6675 ; IDE command codes (or at least the ones we use!)... 6676 0220 CMDEDD=220 ; execute device diagnostic 6677 0354 CMDIDD=354 ; identify device 6678 0040 CMDRDS=040 ; read sectors with retry 6679 0060 CMDWRS=060 ; write sectors with retry 6680 0341 CMDSUP=341 ; spin up 6681 0340 CMDSDN=340 ; spin down PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 163 Initialize IDE Drive and Interface BTS6120.plx 6682 .TITLE Initialize IDE Drive and Interface 6683 6684 6685 ; This routine will initialize the IDE interface by configuring the 8255 6686 ; PPI and then asserting the IDE RESET signal to the drive. It then selects 6687 ; the master drive and waits for it to become ready, after which it returns. 6688 ; If there is no drive attached, or if the hardware is broken, then we'll time 6689 ; out after approximately 30 seconds of waiting for the drive to signal a 6690 ; ready status. 6691 ; 6692 ; Normally this routine will return with the AC and LINK both cleared, but 6693 ; if the drive reports an error then on return the LINK will be set and the 6694 ; drive's error status will be in the AC. In the case of a timeout, the 6695 ; LINK will be set and the AC will be -1 on return. 6696 11013 7200 IDEINI: CLA ; ... 6697 11014 3022 DCA DKSIZE ; zero means no disk is installed 6698 11015 1375 TAD [IDEINP] ; PPI ports A and B are input and C is output 6699 11016 6477 PWCR ; ... 6700 11017 6476 PWPC ; clear all port C control lines 6701 11020 1374 TAD [SETDRE] ; set RESET L 6702 11021 6477 PWCR ; ... 6703 11022 1377 TAD [-10] ; according to the ATA specification, 6704 11023 7001 IAC ; ... we must leave RESET asserted for at 6705 11024 7440 SZA ; ... least 25 microseconds 6706 11025 5223 JMP .-2 ; 6707 11026 1373 TAD [CLRDRE] ; deassert RESET L 6708 11027 6477 PWCR ; ... 6709 6710 11030 1372 TAD [345] ; select the master drive, 512 byte sectors, 6711 11031 4771 JMS @[IDEWRR] ; ... and logical block addressing (LBA) mode 6712 11032 0106 REGLB3 ; ... 6713 6714 11033 4770 JMS @[IDERDR] ; quick check: read status reg 6715 11034 0107 REGSTS ; ... 6716 11035 1367 TAD [-345] ; if it's the same value as the last write, 6717 11036 7440 SZA ; there is almost certainly nothing there 6718 11037 5766 JMP @[WREADY] ; something... do a more complete check 6719 6720 11040 7360 CLA CLL CML CMA ; return with AC = -1 and the LINK set 6721 11041 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 164 Identify IDE/ATA Device BTS6120.plx 6722 .TITLE Identify IDE/ATA Device 6723 6724 6725 ; This routine will execute the ATA IDENTIFY DEVICE command and store the 6726 ; first 256 bytes of the result, in byte mode, in the panel memory buffer at 6727 ; DSKBUF. One thing to keep in mind is that ATAPI devices (e.g. CDROMs, ZIP 6728 ; disks, etc) ignore this command completely and respond to the ATAPI IDENTIFY 6729 ; PACKET DEVICE command instead. This means that if there are any ATAPI 6730 ; devices attached we'll never see them, which is fine since we don't 6731 ; understand how to talk to ATAPI devices anyway! 6732 ; 6733 ; The drive's response to IDENTIFY DEVICE will be 256 words of sixteen bit 6734 ; data full of device specific data - model number, manufacturer, serial 6735 ; number, drive geometry, maximum size, access time, and tons of other cool 6736 ; stuff. The RDIBUF routine would pack this sixteen bit data into twelve bit 6737 ; words by throwing away the upper four bits of each word, but that doesn't 6738 ; make sense in this case since we'd be destroying most of the useful 6739 ; information. Instead, this routine reads the data in an unpacked format and 6740 ; stores one eight bit byte per PDP-8 word. 6741 ; 6742 ; Unfortunately this would mean that we need a 512 word buffer to store the 6743 ; response, which is too big for our DSKBUF in panel memory. We're in luck, 6744 ; however, because of the 256 words (512 bytes) returned by this command the 6745 ; ATA specification only defines the first 128 - the remaining half of the 6746 ; data is "vendor specific" and undefined. This routine simply throws this 6747 ; part away, and only the first 128 words (256 bytes) of the drive's response 6748 ; are actually returned in the buffer. 6749 ; 6750 ; Like all the disk I/O routines, in the case of an error the LINK will 6751 ; be set and the contents of the drive's error register returned in the AC. 6752 11042 6205 DISKID: .PUSHJ @[WREADY] ; (just in case the drive is busy now) 11043 5766 6753 11044 7430 SZL ; any errors? 6754 11045 6225 .POPJ ; yes - we can go home early! 6755 11046 1365 TAD [CMDIDD] ; send the ATA identify device command 6756 11047 4771 JMS @[IDEWRR] ; by writing it to the command register 6757 11050 0107 REGCMD ; ... 6758 11051 6205 .PUSHJ @[WDRQ] ; the drive should ask to transfer data next 11052 5764 6759 11053 7430 SZL ; any errors? 6760 11054 6225 .POPJ ; yes - just give up 6761 6762 ; Get ready to ready to transfer data from the drive to our buffer... 6763 11055 1363 TAD [DSKBUF-1] ; setup BUFPTR to point to DSKBUF 6764 11056 3011 DCA BUFPTR ; ... 6765 11057 1362 TAD [-128.] ; transfer 128 words this time 6766 11060 3051 DCA XFRCNT ; ... 6767 11061 1375 TAD [IDEINP] ; set PPI ports A and B to input mode 6768 11062 6477 PWCR ; ... 6769 11063 1361 TAD [REGDAT] ; make sure the IDE data register is selected 6770 11064 6476 PWPC ; ... 6771 6772 ; Read 256 bytes into the caller's buffer, one byte per word. Big endian 6773 ; ordering (i.e. high byte first) is defined by the ATA specification to give 6774 ; the correct character order for ASCII strings in the device data (e.g. model 6775 ; number, serial number, manufacturer, etc). 6776 11065 1360 IDDEV1: TAD [SETDRD] ; assert DIOR 6777 11066 6477 PWCR ; ... 6778 11067 6470 PRPA ; read port A (the high byte) first 6779 11070 0357 AND [377] ; only eight bits are valid 6780 11071 3411 DCA @BUFPTR ; and store it in the buffer 6781 11072 6471 PRPB ; then read port B (the low byte) 6782 11073 0357 AND [377] ; ... 6783 11074 3411 DCA @BUFPTR ; ... 6784 11075 1356 TAD [CLRDRD] ; deassert DIOR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 165 Identify IDE/ATA Device BTS6120.plx 6785 11076 6477 PWCR ; ... 6786 11077 2051 ISZ XFRCNT ; have we done all 256 bytes? 6787 11100 5265 JMP IDDEV1 ; nope - keep reading 6788 6789 ; We've read our 256 bytes, but the drive still has another 256 more waiting 6790 ; in the buffer. We need to read those and throw them away... 6791 11101 1362 TAD [-128.] ; we still need to read 128 more words 6792 11102 3051 DCA XFRCNT ; ... 6793 11103 1360 IDDEV2: TAD [SETDRD] ; assert DIOR 6794 11104 6477 PWCR ; ... 6795 11105 7000 NOP ; make sure the DIOR pulse is wide enough 6796 11106 7000 NOP ; ... 6797 11107 1356 TAD [CLRDRD] ; and then clear DIOR 6798 11110 6477 PWCR ; ... 6799 11111 2051 ISZ XFRCNT ; have we done all 128? 6800 11112 5303 JMP IDDEV2 ; nope - keep reading 6801 6802 ; Drives report the total number of LBA addressable sectors in words 6803 ; 60 and 61. Sectors are 512 bytes, so simply dividing this value by 2048 6804 ; gives us the total drive size in Mb. This code patches together twelve 6805 ; bits out of the middle of this doubleword, after throwing away the least 6806 ; significant 11 bits to divide by 2048. This allows us to determine the 6807 ; size of drives up to 4Gb in a single 12 bit word. 6808 11113 1755 TAD @[DSKBUF+170] ; get the high byte of the low word 6809 11114 7010 RAR ; throw away the 3 least significant 6810 11115 7012 RTR ; ... 6811 11116 0354 AND [37] ; keep just 5 bits from this byte 6812 11117 3022 DCA DKSIZE ; save it for a minute 6813 11120 1753 TAD @[DSKBUF+173] ; get the low byte of the high word 6814 11121 7006 RTL ; left justify the seven MSBs of it 6815 11122 7006 RTL ; ... 6816 11123 7004 RAL ; ... 6817 11124 0352 AND [7740] ; ... 6818 11125 1022 TAD DKSIZE ; put together all twelve bits 6819 11126 3022 DCA DKSIZE ; ... 6820 6821 ; All done - return success... 6822 11127 7300 CLA CLL ; return with the AC and LINK clear 6823 11130 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 166 Get IDE Disk Size ROM Call BTS6120.plx 6824 .TITLE Get IDE Disk Size ROM Call 6825 6826 6827 ; The get IDE disk size call will return the size of the attached IDE/ATA 6828 ; disk, in megabytes. This call never fails - if no disk is attached it 6829 ; simply returns zero... 6830 ; 6831 ;CALL: 6832 ; PR0 / call SBC6120 ROM firmware 6833 ; 5 / subfunction for get disk size 6834 ; 6835 ; 6836 11131 7300 GETDKS: CLA CLL ; ignore anything in the AC 6837 11132 1022 TAD DKSIZE ; and return the disk size 6838 11133 6225 .POPJ ; that's all there is to it! 6839 11152 7740 11153 7573 11154 0037 11155 7570 11156 0006 11157 0377 11160 0007 11161 0100 11162 7600 11163 7377 11164 1426 11165 0354 11166 1400 11167 7433 11170 2101 11171 2061 11172 0345 11173 0012 11174 0013 11175 0222 11176 0033 11177 7770 6840 11200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 167 IDE Disk Primary Bootstrap BTS6120.plx 6841 .TITLE IDE Disk Primary Bootstrap 6842 6843 ; This routine will read block zero from IDE disk unit zero into page 6844 ; zero of field zero of main memory. The next step in the usual boot sequence 6845 ; would be to start the secondary bootstrap, but that's up to the caller... 6846 11200 7240 IDBOOT: STA ; point the buffer to page 0 6847 11201 3011 DCA BUFPTR ; ... 6848 11202 1377 TAD [CDF 0] ; of field zero 6849 11203 3776 DCA @[BUFCDF+1] ; ... 6850 11204 3052 DCA BUFPNL ; of main memory 6851 11205 6201 CDF 0 ; PARMAP lives in field 0 6852 11206 1775 TAD @[PARMAP] ; get partition number of unit 0 6853 11207 6211 CDF 1 6854 11210 3020 DCA DKPART ; ... 6855 11211 3021 DCA DKRBN ; block zero 6856 11212 1374 TAD [-128.] ; we only need the first 1/2 of the block 6857 11213 5773 JMP @[DISKRD] ; ... 6858 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 168 Read and Write IDE Sectors BTS6120.plx 6859 .TITLE Read and Write IDE Sectors 6860 6861 ; This routine will read a single sector from the attached IDE drive. 6862 ; The caller should set up DKPART and DKRBN with the disk partition and 6863 ; sector number, and BUFPTR, BUFCDF and BUFPNL with the address of a 6864 ; buffer in 6120 memory. If any errors are encountered, this routine will 6865 ; return with the LINK set and the drive's error status in the AC... 6866 ; side effect: BUFPTR is advanced by the read size 6867 ; HOOK: this function can be intercepted in order to connect a different 6868 ; device interface to all the commands and functions that use the disk 6869 11214 7000 DISKRD: NOP ; HOOK: disk read 6870 11215 7000 NOP 6871 11216 7000 NOP 6872 11217 3053 DCA BUFSIZ ; save the buffer size 6873 6874 ; See if there really is a hard disk attached. If not, then immediately 6875 ; take the error return with the AC set to -1. 6876 11220 1022 TAD DKSIZE ; if there is a disk attached 6877 11221 7640 SZA CLA ; then DKSIZE will be non-zero 6878 11222 5225 JMP DRD1 ; it is - it's safe to proceed 6879 11223 7360 CLA CLL CML CMA ; no disk - return LINK = 1 and AC = -1 6880 11224 6225 .POPJ ; and quit now 6881 6882 11225 6205 DRD1: .PUSHJ @[WREADY] ; wait for the drive to become ready 11226 5772 6883 11227 7430 SZL ; any errors detected?? 6884 11230 6225 .POPJ ; yes - quit now 6885 11231 6205 .PUSHJ SETLBA ; set up the disk's LBA registers 11232 5310 6886 11233 1371 TAD [CMDRDS] ; read sector with retry command 6887 11234 4770 JMS @[IDEWRR] ; write that to the command register 6888 11235 0107 REGCMD ; ... 6889 11236 6205 .PUSHJ @[WDRQ] ; now wait for the drive to finish 11237 5767 6890 11240 7430 SZL ; any errors detected? 6891 11241 6225 .POPJ ; yes - quit now 6892 11242 1053 TAD BUFSIZ ; no - transfer data 6893 11243 5766 JMP @[RDIBUF] ; ... from the sector buffer to memory 6894 6895 6896 ; This routine will write a single sector to the attached IDE drive. Except 6897 ; for the direction of data transfer, it's basically the same as DISKRD, 6898 ; including all parameters and error returns. 6899 ; HOOK: this function can be intercepted in order to connect a different 6900 ; device interface to all the commands and functions that use the disk 6901 11244 7000 DISKWR: NOP ; HOOK: disk write 6902 11245 7000 NOP 6903 11246 7000 NOP 6904 11247 3053 DCA BUFSIZ ; save the caller's record size 6905 6906 ; See if there really is a hard disk attached. If not, then immediately 6907 ; take the error return with the AC set to -1. 6908 11250 1022 TAD DKSIZE ; if there is a disk attached 6909 11251 7640 SZA CLA ; then DKSIZE will be non-zero 6910 11252 5255 JMP DWR1 ; it is - it's safe to proceed 6911 11253 7360 CLA CLL CML CMA ; no disk - return LINK = 1 and AC = -1 6912 11254 6225 .POPJ ; and quit now 6913 6914 11255 6205 DWR1: .PUSHJ @[WREADY] ; wait for the drive to become ready 11256 5772 6915 11257 7430 SZL ; did we encounter an error ? 6916 11260 6225 .POPJ ; yes - just give up now 6917 11261 6205 .PUSHJ SETLBA ; set up the disk address registers 11262 5310 6918 11263 1365 TAD [CMDWRS] ; write sector with retry command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 169 Read and Write IDE Sectors BTS6120.plx 6919 11264 4770 JMS @[IDEWRR] ; write that to the command register 6920 11265 0107 REGCMD ; ... 6921 11266 6205 .PUSHJ @[WDRQ] ; wait for the drive to request data 11267 5767 6922 11270 7430 SZL ; did the drive detect an error instead? 6923 11271 6225 .POPJ ; yes - just give up 6924 11272 1053 TAD BUFSIZ ; nope - transfer the data 6925 11273 6205 .PUSHJ @[WRIBUF] ; ... to the sector buffer from memory 11274 5764 6926 6927 ; There's a subtle difference in the order of operations between reading and 6928 ; writing. In the case of writing, we send the WRITE SECTOR command to the 6929 ; drive, transfer our data to the sector buffer, and only then does the 6930 ; drive actually go out and access the disk. This means we have to wait 6931 ; one more time for the drive to actually finish writing, because only then 6932 ; can we know whether it actually worked or not! 6933 11275 5772 JMP @[WREADY] ; wait for the drive to finish writing PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 170 Spin Up and Spin Down IDE Drive BTS6120.plx 6934 .TITLE Spin Up and Spin Down IDE Drive 6935 6936 6937 ; This routine will send a spin up command to the IDE drive and then wait 6938 ; for it to finish. This command will take a fairly long time under normal 6939 ; conditions. Worse, since this is frequently the first command we send to 6940 ; a drive, if there's no drive attached at all we'll have to wait for it 6941 ; to time out. If any errors are encountered then the LINK will be set on 6942 ; return and the contents of the drive's error register will be in the AC. 6943 11276 7200 SPINUP: CLA ; ... 6944 11277 1363 TAD [CMDSUP] ; send the spin up command to the drive 6945 11300 4770 JMS @[IDEWRR] ; by writing it to the command register 6946 11301 0107 REGCMD ; ... 6947 11302 5772 JMP @[WREADY] ; wait for the drive to become ready 6948 6949 6950 ; This routine will send a spin down command. Drives are not required by 6951 ; the standard to implement this command, so there's no guarantee that any 6952 ; thing will actually happen! 6953 11303 7200 SPINDN: CLA ; ... 6954 11304 1362 TAD [CMDSDN] ; send the spin down command to the drive 6955 11305 4770 JMS @[IDEWRR] ; ... 6956 11306 0107 REGCMD ; ... 6957 11307 5772 JMP @[WREADY] ; and wait for it to finish PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 171 Setup IDE Unit, LBA and Sector Count Registers BTS6120.plx 6958 .TITLE Setup IDE Unit, LBA and Sector Count Registers 6959 6960 6961 ; This routine will set up the IDE logical block address (LBA) registers 6962 ; according to the current disk address in locations DKPART and DKRBN. On IDE 6963 ; drives the sector number is selected via the cylinder and sector registers in 6964 ; the register file, but in the case of LBA mode these registers simply form a 6965 ; 24 bit linear sector number. In this software the disk partition number, in 6966 ; DKPART, gives the upper twelve bits of the address and the current sector 6967 ; number, in DKRBN, gives the lower twelve bits. 6968 ; 6969 ; This routine does not detect any error conditions... 6970 11310 7200 SETLBA: CLA ; just in case! 6971 11311 1021 TAD DKRBN ; get the lower 12 bits of of the LBA 6972 11312 4770 JMS @[IDEWRR] ; and write the lowest 8 bits to LBA0 6973 11313 0103 REGLB0 ; (the upper 4 bits are ignored) 6974 11314 1021 TAD DKRBN ; now get the upper 4 bits of the sector number 6975 11315 7002 BSW ; shift right eight bits 6976 11316 7012 RTR ; ... 6977 11317 0361 AND [17] ; get rid of the extra junk 6978 11320 3344 DCA LBATMP ; ... 6979 11321 1020 TAD DKPART ; get the disk partition number 6980 11322 7006 RTL ; shift them left four bits 6981 11323 7006 RTL ; ... 6982 11324 0360 AND [360] ; and isolate just four bits of that 6983 11325 1344 TAD LBATMP ; and build the middle byte of the LBA 6984 11326 4770 JMS @[IDEWRR] ; set that register next 6985 11327 0104 REGLB1 ; ... 6986 11330 1020 TAD DKPART ; get the partition one more time 6987 11331 7012 RTR ; shift it right four more bits 6988 11332 7012 RTR ; ... 6989 11333 4770 JMS @[IDEWRR] ; to make the upper byte of the 24 bit LBA 6990 11334 0105 REGLB2 ; ... 6991 6992 ; Note that the final four bits of the LBA are in LBA3 (the head and drive 6993 ; select register). Since we can only support 24 bit LBAs, these are unused. 6994 ; The IDEINI routine initializes them to zero at the same time it selects the 6995 ; master drive, and we never change 'em after that. At the same time, IDEINI 6996 ; also selects LBA addressing mode (which is obviously very important to us!) 6997 ; and 512 byte sectors. 6998 11335 1362 TAD [340] ; select the master drive, 512 byte sectors, 6999 11336 4770 JMS @[IDEWRR] ; ... and logical block addressing (LBA) mode 7000 11337 0106 REGLB3 ; ... 7001 7002 ; Always load the sector count register with one... 7003 11340 7201 NL0001 ; write 1 7004 11341 4770 JMS @[IDEWRR] ; ... 7005 11342 0102 REGCNT ; to the sector count register 7006 11343 6225 .POPJ ; that's all we have to do 7007 7008 ; Temporary storage for SETLBA... 7009 11344 LBATMP: .BLOCK 1 11360 0360 11361 0017 11362 0340 11363 0341 11364 1600 11365 0060 11366 1646 11367 1426 11370 2061 11371 0040 11372 1400 11373 1214 11374 7600 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 172 Setup IDE Unit, LBA and Sector Count Registers BTS6120.plx 11375 0020 11376 2212 11377 6201 7010 11400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 173 Wait for IDE Drive Ready BTS6120.plx 7011 .TITLE Wait for IDE Drive Ready 7012 7013 7014 ; This routine tests for the DRIVE READY bit set in the status register and 7015 ; at the same time for the DRIVE BUSY bit to be clear. READY set means that 7016 ; the drive has power and is spinning, and BUSY clear means that it isn't 7017 ; currently executing a command. The combination of these two conditions means 7018 ; that the drive is ready to accept another command. Normally this routine 7019 ; will return with both the AC and the LINK cleared, however if the drive sets 7020 ; the ERROR bit in its status register then it will return with the LINK set 7021 ; and the contents of the drive's error register in the AC. 7022 ; 7023 ; If there is no drive connected, or if the drive fails for some reason, 7024 ; then there is the danger that this routine will hang forever. To avoid 7025 ; that it also implements a simple timeout, and if the drive doesn't become 7026 ; ready within a certain period of time it will return with the LINK set and 7027 ; the AC equal to -1. If the system has just been powered up, then we'll 7028 ; have to wait for the drive to spin up before it becomes ready, and that can 7029 ; take a fairly long time. To be safe, the timeout currently stands at a 7030 ; full 30 seconds! 7031 11400 1377 WREADY: TAD [7550] ; initialize the outer timeout counter 7032 11401 3225 DCA RDYTMO+1 ; ... 7033 11402 3224 DCA RDYTMO ; and the inner counter is always cleared 7034 11403 4776 WREAD1: JMS @[IDERDR] ; go read the status register 7035 11404 0107 REGSTS ; (register to read) 7036 11405 7110 CLL RAR ; test the error bit first (AC11) 7037 11406 7430 SZL ; ??? 7038 11407 5775 JMP @[DRVERR] ; give up now if the drive reports an error 7039 11410 7004 RAL ; restore the original status 7040 11411 0374 AND [STSBSY+STSRDY] ; test both the READY and BUSY bits 7041 11412 1373 TAD [-STSRDY] ; is READY set and BUSY clear? 7042 11413 7020 CML ; (the last TAD will have set the link!) 7043 11414 7650 SNA CLA ; ??? 7044 11415 6225 .POPJ ; yes - return now with the AC and LINK clear 7045 11416 2224 ISZ RDYTMO ; increment the inner timeout counter 7046 11417 5203 JMP WREAD1 ; no overflow yet 7047 11420 2225 ISZ RDYTMO+1 ; when the inner counter overflows, increment 7048 11421 5203 JMP WREAD1 ; ... the outer counter too 7049 7050 ; Here in the case of a drive time out... 7051 11422 7360 CLA CLL CML CMA ; return with AC = -1 and the LINK set 7052 11423 6225 .POPJ ; ... 7053 7054 ; Temporary storage for WREADY... 7055 11424 RDYTMO: .BLOCK 2 ; a double word time out counter 7056 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 174 Wait for IDE Data Request BTS6120.plx 7057 .TITLE Wait for IDE Data Request 7058 7059 ; This routine will wait for the DRQ bit to set in the drive status register. 7060 ; This bit true when the drive is ready to load or unload its sector buffer, 7061 ; and normally a call to this routine will be immediately followed by a call 7062 ; to ether RDIBUF or WRIBUF. Normally this routine will return with both the 7063 ; LINK and the AC cleared, however if the drive sets its error bit then the 7064 ; LINK will be 1 on return and the drive's error status will be in the AC. 7065 ; 7066 ; WARNING - unlike WREADY, this routine does not have a timeout! 7067 11426 4776 WDRQ: JMS @[IDERDR] ; read the drive status register 7068 11427 0107 REGSTS ; ... 7069 11430 7110 CLL RAR ; test the error bit (AC11) 7070 11431 7430 SZL ; is it set? 7071 11432 5242 JMP DRVERR ; yes - give the error return 7072 11433 7004 RAL ; no - restore the original status value 7073 11434 0372 AND [STSBSY+STSDRQ] ; and test the BUSY and DRQ flags 7074 11435 1371 TAD [-STSDRQ] ; wait for BUSY clear and DRQ set 7075 11436 7020 CML ; (the last TAD will have set the link!) 7076 11437 7640 SZA CLA ; well? 7077 11440 5226 JMP WDRQ ; nope - keep waiting 7078 11441 6225 .POPJ ; yes - return with AC and LINK cleared! 7079 7080 ; We get here if the drive sets the error flag in the status register. In 7081 ; this case we return with the link bit set and the contents of the drive 7082 ; error register in the AC. 7083 11442 4776 DRVERR: JMS @[IDERDR] ; read the drive error register 7084 11443 0101 REGERR ; ... 7085 11444 7120 STL ; and be sure the link is set 7086 11445 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 175 RAM Disk Diagnostics BTS6120.plx 7087 .TITLE RAM Disk Diagnostics 7088 7089 ; This routine will do a simple test of the RAM disk array to determine 7090 ; whether each SRAM chip, from 0 to 7, is installed. If a given chip is 7091 ; installed, then we do another simple test to determine whether it is a 7092 ; 512K or 128K device, and then update the RDSIZE array accordingly. 7093 ; Because of the way disk sectors are laid out, only the first 4032 bytes 7094 ; (21 * 192) of every 4Kb bank are actually used. The last 64 bytes of each 7095 ; bank are available to us to use any way we like, including as a RAM test. 7096 ; 7097 ; There's one nasty complication here - the pin that corresponds to A17 on 7098 ; the 512K SRAM chips is actually an alternate chip enable on the 128K chips. 7099 ; Worse, this alternate enable is active HIGH, which means that A17 must be 7100 ; one or 128K chips won't talk at all. Fortunately, the pin that corresponds 7101 ; to A18 is a no connect on the 128K chips, so we can safely leave it zero. 7102 ; This explains the strange bank numbers selected in this test! 7103 ; 7104 11446 3043 RDTEST: DCA RAMSIZ ; clear the total RAM size 7105 7106 ; Clear the entire RDSIZE array, even if we have fewer than 8 SRAMs... 7107 11447 1371 TAD [-10] ; RDZISE always holds 8 units 7108 11450 3024 DCA RDUNIT ; count them here 7109 11451 1370 TAD [RDSIZE-1] ; and point to the RDSIZE array 7110 11452 3012 DCA XX1 ; (an auto-index register) 7111 11453 3412 DCA @XX1 ; clear another entry 7112 11454 2024 ISZ RDUNIT ; have we done them all 7113 11455 5253 JMP .-2 ; no - keep clearing 7114 ; yes - start testing with RDUNIT = 0 ! 7115 7116 ; First test to see if this chip is even installed by writing alternating 7117 ; bit patterns to the last two locations and reading them back. If that works, 7118 ; then there must be something there! 7119 11456 6205 RDTES0: .PUSHJ @[RAMSEL] ; and set up RAMCDF and SIZPTR 11457 5767 7120 11460 1366 TAD [32.] ; test bank 32 so that A17 will be set 7121 11461 6410 LDAR ; ... 7122 11462 4765 JMS @[RAMCDF] ; change the DF to select the unit 7123 11463 6403 MM3 ; and enable the SRAM array 7124 11464 1364 TAD [252] ; write alternating bits to the last two bytes 7125 11465 3763 DCA @[7776] ; ... 7126 11466 1362 TAD [125] ; ... 7127 11467 3761 DCA @[7777] ; ... 7128 11470 1763 TAD @[7776] ; now read 'em back 7129 11471 1761 TAD @[7777] ; and add them up 7130 11472 7001 IAC ; the sum should be 377, so make it 400 7131 11473 0360 AND [377] ; and remember RAM disk is only 8 bits wide 7132 11474 7640 SZA CLA ; did it work?? 7133 11475 5310 JMP RDTES1 ; no - this chip doesn't exist 7134 7135 ; Some kind of SRAM chip is installed, and now we need to decide whether its 7136 ; 128K or 512K. The 128K chips ignore A18, so one easy test is to select 7137 ; bank 96 (which, to a 128K chip is the same as bank 32), zero out a location 7138 ; that we just tested, and then go back to bank 32 to see if it changed. 7139 11476 1357 TAD [96.] ; select bank 96 7140 11477 6410 LDAR ; which doesn't exist in a 128K chip 7141 11500 3761 DCA @[7777] ; this location in bank 0 used to hold 125 7142 11501 1366 TAD [32.] ; back to bank 32 7143 11502 6410 LDAR ; ... 7144 11503 1761 TAD @[7777] ; and see what we've got 7145 11504 0360 AND [377] ; remember RAM disk is only 8 bits wide 7146 11505 7640 SZA CLA ; if it's zero, then we have a 128K chip 7147 11506 1356 TAD [RAM512-RAM128]; nope - this must be a full 512K SRAM! 7148 11507 1355 TAD [RAM128] ; only 128K, but better than nothing 7149 7150 ; Store the chip size in RDSIZE and accumulate the total size... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 176 RAM Disk Diagnostics BTS6120.plx 7151 11510 6402 RDTES1: MM2 ; return to the default memory map 7152 11511 6211 CDF 1 ; and field 7153 11512 3444 DCA @SIZPTR ; store the size in RDSIZE[unit] 7154 11513 1444 TAD @SIZPTR ; ... 7155 11514 7450 SNA ; was there any chip here at all? 7156 11515 5325 JMP RDTES2 ; no - we can skip this part 7157 11516 7710 SPA CLA ; KLUDGE - skip if this was a 128K chip 7158 11517 1354 TAD [512.-128.] ; add 512K to the total RAM size 7159 11520 1353 TAD [128.] ; add 128K " " " " " 7160 ; Now it's time for a major hack. If we have a full eight 512K SRAM chips 7161 ; installed, then RAMSIZ will be 4096KB, or zero in the twelve bit world! 7162 ; If we ever find that, after adding the size of this chip, RAMSIZ is zero 7163 ; then we know that situation has occurred. The only thing we can to is to 7164 ; set RAMSIZ to 4095 instead of 4096 - that way, at least, it doesn't look 7165 ; like we have nothing... 7166 11521 1043 TAD RAMSIZ ; ... 7167 11522 7450 SNA ; did we reach 4096K ??? 7168 11523 7240 STA ; yes - set it to 4095 instead 7169 11524 3043 DCA RAMSIZ ; ... 7170 7171 ; On to the next unit, if there are any more left... 7172 11525 2024 RDTES2: ISZ RDUNIT ; go on to the next unit 7173 11526 1046 TAD RDTYPE ; get the RAM disk type 7174 11527 7700 SMA CLA ; skip if it's a DS1221 or IOB6120 card 7175 11530 1352 TAD [-4] ; no - the DS1231 card supports 8 units 7176 11531 1352 TAD [-4] ; and the others only 4 7177 11532 1024 TAD RDUNIT ; have we done all eight ? 7178 11533 7640 SZA CLA ; ??? 7179 11534 5256 JMP RDTES0 ; no - keep checking 7180 11535 1043 TAD RAMSIZ ; yes - return the total RAM disk size 7181 11536 6225 .POPJ ; and that's it 7182 11552 7774 11553 0200 11554 0600 11555 1240 11556 3740 11557 0140 11560 0377 11561 7777 11562 0125 11563 7776 11564 0252 11565 0744 11566 0040 11567 0713 11570 0032 11571 7770 11572 0210 11573 7700 11574 0300 11575 1442 11576 2101 11577 7550 7183 11600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 177 Write IDE Sector Buffer BTS6120.plx 7184 .TITLE Write IDE Sector Buffer 7185 7186 7187 ; This routine will write PDP-8 twelve bit words to the IDE drive's sixteen 7188 ; bit data (sector) buffer. IDE drives naturally transfer data in sixteen bit 7189 ; words, and we simply store each twelve bit word zero extended. This wastes 7190 ; 25% of the drive's capacity, but in these days of multiple gigabyte disks, 7191 ; that hardly seems important. This also means that 256 PDP-8 words exactly 7192 ; fill one IDE sector, which is very convenient for OS/8! 7193 ; 7194 ; The caller is expected to set up BUFPTR, BUFCDF and BUFPNL to point to the 7195 ; buffer in 6120 memory. The negative of the buffer size should be passed in 7196 ; the AC, however we must always write exactly 256 words to the drive regard- 7197 ; less of the buffer size. If the buffer is smaller than that, then the last 7198 ; word is simply repeated until we've filled the entire sector. This is 7199 ; necessary for OS/8 handler "half block" writes. 7200 ; 7201 ; This routine does not wait for the drive to set DRQ, nor does it check the 7202 ; drive's status for errors. Those are both up to the caller. 7203 11600 3053 WRIBUF: DCA BUFSIZ ; save the actual buffer size 7204 11601 1377 TAD [-256.] ; but always transfer 256 words, regardless 7205 11602 3051 DCA XFRCNT ; ... 7206 11603 1376 TAD [IDEOUT] ; and set ports A and B to output mode 7207 11604 6477 PWCR ; ... 7208 11605 1375 TAD [REGDAT] ; make sure the IDE data register is addressed 7209 11606 6476 PWPC ; ... 7210 11607 4774 JMS @[BUFCDF] ; change to the buffer's field 7211 7212 ; Transfer 256 twelve bit words into 256 sixteen bit words... 7213 11610 1411 WRIBU1: TAD @BUFPTR ; and get the next data word 7214 11611 3312 DCA BUFTMP ; save it temporarily 7215 11612 1312 TAD BUFTMP ; ... 7216 11613 6475 PWPB ; write the lowest 8 bits to port B 7217 11614 1312 TAD BUFTMP ; then get the upper four bits 7218 11615 7002 BSW ; ... 7219 11616 7012 RTR ; ... 7220 11617 0373 AND [17] ; ensure that the extra bits are zero 7221 11620 6474 PWPA ; and write the upper four bits to port A 7222 11621 1372 TAD [SETDWR] ; assert DIOW 7223 11622 6477 PWCR ; ... 7224 11623 1371 TAD [CLRDWR] ; and then clear it 7225 11624 6477 PWCR ; ... 7226 11625 2051 ISZ XFRCNT ; have we done 256 words?? 7227 11626 7410 SKP ; no - keep going 7228 11627 5240 JMP WRIBU3 ; yes - always stop now 7229 11630 2053 ISZ BUFSIZ ; have we filled the buffer ? 7230 11631 5210 JMP WRIBU1 ; nope - keep copying 7231 7232 ; Here when we've emptied the 6120 buffer, but if we haven't done 256 words 7233 ; we have to keep going until we've filled the drive's sector buffer. All we 7234 ; need to do is to keep asserting DIOW, which simply repeats the last word 7235 ; written! 7236 11632 1372 WRIBU2: TAD [SETDWR] ; assert DIOW 7237 11633 6477 PWCR ; ... 7238 11634 1371 TAD [CLRDWR] ; and deassert DIOW 7239 11635 6477 PWCR ; ... 7240 11636 2051 ISZ XFRCNT ; have we finished the sector? 7241 11637 5232 JMP WRIBU2 ; nope 7242 7243 ; Restore the PPI ports to input mode and return. Note that some disk 7244 ; I/O routines JMP to WRIBUF as the last step, so it's important that we 7245 ; always return with the AC and LINK cleared to indicate success. 7246 11640 6211 WRIBU3: CDF 1 ; return to our field 7247 11641 6276 SPD ; and to panel memory 7248 11642 1370 TAD [IDEINP] ; reset ports A and B to input PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 178 Write IDE Sector Buffer BTS6120.plx 7249 11643 6477 PWCR ; ... 7250 11644 7300 CLA CLL ; return success 7251 11645 6225 .POPJ ; all done here PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 179 Read IDE Sector Buffer BTS6120.plx 7252 .TITLE Read IDE Sector Buffer 7253 7254 7255 ; This routine will read sixteen bit words from the IDE drive's sector 7256 ; buffer and store them in twelve bit PDP-8 memory words. Data is converted 7257 ; from sixteen to twelve bits by the simple expedient of discarding the upper 7258 ; four bits of each word - it can't get much easier than that! 7259 ; 7260 ; The caller is expected to set up BUFPTR, BUFCDF and BUFPNL to point to the 7261 ; buffer in 6120 memory. The negative of the buffer size should be passed in 7262 ; the AC. This is the number of words that will be stored in the buffer, 7263 ; however we'll always read exactly 256 words from the drive regardless of 7264 ; the buffer size. If the buffer is smaller than this then the extra words 7265 ; are simply discarded. This is necessary for OS/8 handler "half block" reads. 7266 ; 7267 ; Like WRIBUF, this routine does not wait for the drive to set DRQ, nor does 7268 ; it check the drive's status for errors. Those are both up to the caller. 7269 11646 3053 RDIBUF: DCA BUFSIZ ; save the actual buffer size 7270 11647 1377 TAD [-256.] ; but always transfer 256 words, regardless 7271 11650 3051 DCA XFRCNT ; ... 7272 11651 1370 TAD [IDEINP] ; and set ports A and B to input mode 7273 11652 6477 PWCR ; ... 7274 11653 1375 TAD [REGDAT] ; make sure the IDE data register is addressed 7275 11654 6476 PWPC ; ... 7276 11655 4774 JMS @[BUFCDF] ; change to the buffer's field 7277 7278 ; Transfer 256 twelve bit words... 7279 11656 1367 RDIBU1: TAD [SETDRD] ; assert DIOR 7280 11657 6477 PWCR ; ... 7281 11660 6471 PRPB ; capture the lower order byte 7282 11661 0366 AND [377] ; remove any junk bits, just in case 7283 11662 3312 DCA BUFTMP ; and save that for a minute 7284 11663 6470 PRPA ; then capture the high byte 7285 11664 0373 AND [17] ; we only want four bits from that 7286 11665 7002 BSW ; shift it left eight bits 7287 11666 7106 CLL RTL ; ... 7288 11667 1312 TAD BUFTMP ; assemble a complete twelve bit word 7289 11670 3411 DCA @BUFPTR ; and store it in the buffer 7290 11671 1365 TAD [CLRDRD] ; finally we can deassert DIOR 7291 11672 6477 PWCR ; ... 7292 11673 2051 ISZ XFRCNT ; have we done 256 words?? 7293 11674 7410 SKP ; no - keep going 7294 11675 5306 JMP RDIBU3 ; yes - always stop now 7295 11676 2053 ISZ BUFSIZ ; have we filled the buffer ? 7296 11677 5256 JMP RDIBU1 ; nope - keep copying 7297 7298 ; Here when we've filled the 6120 buffer, but if we haven't done 256 words 7299 ; we have to keep going until we've emptied the drive's sector buffer too. 7300 ; All we need to do is to keep asserting DIOR - there's no need to actually 7301 ; capture the data! 7302 11700 1367 RDIBU2: TAD [SETDRD] ; assert DIOR 7303 11701 6477 PWCR ; ... 7304 11702 1365 TAD [CLRDRD] ; and deassert DIOR 7305 11703 6477 PWCR ; ... 7306 11704 2051 ISZ XFRCNT ; have we finished the sector? 7307 11705 5300 JMP RDIBU2 ; nope 7308 7309 ; Restore the ROM field and memory space and return. Note that some disk 7310 ; I/O routines JMP to RDIBUF as the last step, so it's important that we 7311 ; always return with the AC and LINK cleared to indicate success. 7312 11706 6211 RDIBU3: CDF 1 ; ... 7313 11707 6276 SPD ; ... 7314 11710 7300 CLA CLL ; always return success 7315 11711 6225 .POPJ ; all done here 7316 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 180 Read IDE Sector Buffer BTS6120.plx 7317 ; Temporary storage for RDIBUF and WRIBUF... 7318 11712 BUFTMP: .BLOCK 1 ; temporary for packing and unpacking 7319 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 181 Initialize Disk Partition Map BTS6120.plx 7320 .TITLE Initialize Disk Partition Map 7321 7322 7323 ; This routine will initialize the disk partition map so that unit 0 7324 ; maps to partition 0, unit 1 maps to partition 1, etc... This is the 7325 ; default partition mapping used after a power on and remains in effect 7326 ; until changed by an OS/8 program with the "Set Partition Mapping" PR0 7327 ; subfunction. 7328 7329 11713 7200 INIPMP: CLA ; just in case... 7330 11714 1364 TAD [-8.] ; we are going to init 8 units 7331 11715 3020 DCA DKPART 7332 11716 1373 TAD [PARMAP-1] ; set up an auto index register 7333 11717 3012 DCA XX1 ; ... to address the partition map 7334 11720 6402 MM2 7335 11721 7215 INIPM1: NL0010 7336 11722 1020 TAD DKPART ; get the current partition/unit 7337 11723 6201 CDF 0 7338 11724 3412 DCA @XX1 ; and set the next entry in the map 7339 11725 6211 CDF 1 7340 11726 2020 ISZ DKPART 7341 11727 5321 JMP INIPM1 ; ... 7342 11730 7300 CLA CLL 7343 11731 6225 .POPJ 7344 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 182 Set Disk Partition Map ROM Call BTS6120.plx 7345 .TITLE Set Disk Partition Map ROM Call 7346 7347 7348 ; This routine handles the "Set Disk Partition Mapping" (6) PR0 subfunction, 7349 ; which simply sets the partition number for the specified OS/8 unit. This 7350 ; change takes effect immediately, so if you've booted from the IDE disk 7351 ; you'll want to be a little careful about remapping the system partition! 7352 ; This function returns with the LINK set if an error occurs, currently the 7353 ; only failure that can happen is if the unit number is .GT. 7. Note that 7354 ; no range checking is done on the partition number to ensure that it fits 7355 ; within the disk size - if it doesn't we'll simply get I/O errors when OS/8 7356 ; attempts to access that partition. 7357 ; 7358 ;CALL: 7359 ; TAD (part / load the partition number into the AC 7360 ; PR0 / invoke the ROM monitor 7361 ; 6 / subfunction for Set disk partition 7362 ; / OS/8 unit to be changed, 0..7 7363 ; / LINK set if unit .GT. 7 7364 ; 7365 11732 3020 SETPMP: DCA DKPART ; save the partition number for a minute 7366 11733 6205 .PUSHJ @[GETARG] ; and get the unit number 11734 5763 7367 11735 3023 DCA DKUNIT ; ... 7368 11736 1023 TAD DKUNIT ; ... 7369 11737 7100 CLL ; be sure the link is in a known state 7370 11740 1364 TAD [-10] ; see if the unit number is legal 7371 11741 7630 SZL CLA ; the link will be set if it isn't 7372 11742 6225 .POPJ ; take the error return w/o changing anything 7373 11743 1023 TAD DKUNIT ; construct an index to the partition map 7374 11744 1373 TAD [PARMAP-1] ; ... 7375 11745 3012 DCA XX1 ; ... 7376 11746 1020 TAD DKPART ; then get the desired partition number 7377 11747 6201 CDF 0 ; PARAM lives in field 0 7378 11750 3412 DCA @XX1 ; and change it 7379 11751 6222 CIF 2 7380 11752 6205 .PUSHJ @[WRPSS] ; update NVRAM 11753 5762 7381 11754 7300 CLL CLA 7382 11755 6225 .POPJ ; return with the LINK and AC both clear 7383 11762 0243 11763 0241 11764 7770 11765 0006 11766 0377 11767 0007 11770 0222 11771 0010 11772 0011 11773 0017 11774 2211 11775 0100 11776 0200 11777 7400 7384 12000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 183 Get Disk Partition Map ROM Call BTS6120.plx 7385 .TITLE Get Disk Partition Map ROM Call 7386 7387 7388 ; This routine handles the "Get Disk Partition Mapping" (7) PR0 subfunction, 7389 ; which simply returns the partition number currently associated with a 7390 ; specific OS/8 unit. The only way it can fail is if the unit number is 7391 ; greater than 7! 7392 ; 7393 ;CALL: 7394 ; PR0 / invoke the ROM monitor 7395 ; 7 / subfunction for get disk partition 7396 ; / OS/8 unit to be changed, 0..7 7397 ; / with partition number in the AC 7398 ; 7399 12000 6205 GETPMP: .PUSHJ @[GETARG] ; and get the unit number 12001 5777 7400 12002 3023 DCA DKUNIT ; ... 7401 12003 7100 CLL ; be sure the link is in a known state 7402 12004 1376 TAD [-10] ; see if the unit number is legal 7403 12005 1023 TAD DKUNIT ; ... 7404 12006 7630 SZL CLA ; the link will be set if it isn't 7405 12007 6225 .POPJ ; take the error return 7406 12010 1023 TAD DKUNIT ; construct an index to the partition map 7407 12011 1375 TAD [PARMAP-1] ; ... 7408 12012 3012 DCA XX1 ; ... 7409 12013 6201 CDF 0 ; PARMAP lives in field 0 7410 12014 1412 TAD @XX1 ; and get the current partition 7411 12015 6211 CDF 1 7412 12016 6225 .POPJ ; return with partition in the AC and LINK=0 7413 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 184 IDE Disk Read/Write ROM Call BTS6120.plx 7414 .TITLE IDE Disk Read/Write ROM Call 7415 7416 7417 ; The calling sequence for the PR0 IDE disk R/W function is: 7418 ; 7419 ; PR0 7420 ; 0004 / panel function code for IDE disk I/O 7421 ; / R/W bit, page count, buffer field and unit 7422 ; / buffer address 7423 ; / starting block number 7424 ; / if any errors occur, the LINK will be set and the 7425 ; / the drive's error register are in the AC 7426 ; 7427 ; Except for the function code, the use of block numbers instead of page 7428 ; numbers, and the error codes, this calling sequence is identical to the 7429 ; RAM disk I/O PR0 subfunction! 7430 ; 7431 12017 6205 DISKRW: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 12020 5774 7432 12021 6205 .PUSHJ @[GETARG] ; and lastly get the disk block 12022 5777 7433 12023 3021 DCA DKRBN ; ... 7434 7435 ; The unit number is really just an index into the partition table and, 7436 ; since it's limited to three bits and eight units are supported, there's 7437 ; no need to range check it! 7438 12024 1047 DKRW0: TAD MUUO ; get the unit number 7439 12025 0373 AND [7] ; ... 7440 12026 1375 TAD [PARMAP-1] ; create an index to the partition table 7441 12027 3012 DCA XX1 ; ... 7442 12030 6201 CDF 0 ; PARMAP lives in field 0 7443 12031 1412 TAD @XX1 ; get the actual partition number 7444 12032 6211 CDF 1 7445 12033 3020 DCA DKPART ; ... that's mapped to this unit 7446 7447 ; Set up a pointer to the I/O routine. All of the rest of this code is 7448 ; independent of the direction of data flow... 7449 12034 1047 TAD MUUO ; get the function code 7450 12035 7700 SMA CLA ; should we read (0) or write (1) ? 7451 12036 1372 TAD [DISKRD-DISKWR]; ... read 7452 12037 1371 TAD [DISKWR] ; ... write 7453 12040 3260 DCA DISKIO ; save the address of the routine 7454 7455 ; We must take a minute out to share a word about pages vs blocks. An OS/8 7456 ; handler call specifies the size of the data to be read or written in pages, 7457 ; which are 128 words or exactly 1/2 of a 256 word disk block. This raises 7458 ; the unfortunate possibility that a program could ask to transfer an odd 7459 ; number of pages, which would mean that we'd need to read or write half a 7460 ; block! We can't ignore this problem because it really does happen and there 7461 ; really are OS/8 programs that attempt to transfer an odd number of pages. 7462 ; 7463 ; This is primarily an issue for reading, because if an odd number of pages 7464 ; are to be read we must be very careful to stop copying data to memory after 7465 ; 128 words. If we don't, a page of memory will be corrupted by being over 7466 ; written with the second half of the last disk block! It's also permitted in 7467 ; OS/8 to write an odd number of pages, but since many OS/8 mass storage 7468 ; devices have 256 word sectors it isn't always possible to write half a 7469 ; block. In this case it's undefined what gets written to the last half of 7470 ; the final block - it could be zeros, random garbage, or anything else. 7471 7472 ; This loop reads or writes pages 'till we've done all we're supposed to... 7473 12041 2054 DKRW1: ISZ RWCNT ; is there an odd page left over? 7474 12042 7410 SKP ; nope - it's safe to do a full block 7475 12043 5256 JMP DKRW2 ; yes - go transfer a half block and quit 7476 12044 1370 TAD [-256.] ; transfer two pages this time PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 185 IDE Disk Read/Write ROM Call BTS6120.plx 7477 12045 6205 .PUSHJ @DISKIO ; either read or write 12046 5660 7478 12047 7430 SZL ; were there any errors? 7479 12050 6225 .POPJ ; yes - just abort the transfer now 7480 12051 2021 ISZ DKRBN ; increment the block number for next time 7481 12052 7000 NOP ; (this should never happen, but...) 7482 12053 2054 ISZ RWCNT ; are there more pages left to do ? 7483 12054 5241 JMP DKRW1 ; yup - keep going 7484 12055 6225 .POPJ ; all done - return AC = LINK = 0 7485 7486 ; Here to transfer one, final, half block... 7487 12056 1367 DKRW2: TAD [-128.] ; only do a single page this time 7488 12057 5660 JMP @DISKIO ; transfer it and we're done 7489 7490 ; Local storage for DISKRW... 7491 12060 DISKIO: .BLOCK 1 ; gets a pointer to either DISKRD or DISKWR 7492 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 186 Write IDE Register BTS6120.plx 7493 .TITLE Write IDE Register 7494 7495 7496 ; This routine will write an eight bit value to any IDE drive register, 7497 ; except the data regsister, by toggling all the appropriate PPI port lines. 7498 ; The address of the register, which should include the CS1Fx and CS3Fx bits, 7499 ; is passed in line and the byte to be written is passed in the AC. Note that 7500 ; all IDE registers, with the exception of the data register, are eight bits 7501 ; wide so there's never a need to worry about the upper byte! 7502 ; 7503 ;CALL: 7504 ; TAD [value] ; eight bit value to write to the IDE register 7505 ; JMS IDEWRR 7506 ; xxxx ; IDE register number, plus CS1Fx and CS3Fx bits 7507 ; 7508 ; 7509 12061 0000 IDEWRR: 0 ; CALL HERE WITH A JMS!!! 7510 12062 3322 DCA IDETMP ; save the value to write for a minute 7511 12063 1366 TAD [IDEOUT] ; set ports A and B to output mode 7512 12064 6477 PWCR ; write the PPI control register 7513 12065 1661 TAD @IDEWRR ; get the IDE register address 7514 12066 2261 ISZ IDEWRR ; (skip it when we return) 7515 12067 6476 PWPC ; send the address to the drive via port C 7516 7517 ; Note that we don'e bother to drive the upper data byte (D8..D15) with any 7518 ; particular value. The PPI will have set these bits to zero when we changed 7519 ; the mode to output, but the drive will ignore them anyway. 7520 12070 1322 TAD IDETMP ; get the original data back 7521 12071 6475 PWPB ; (port B drives DD0..DD7) 7522 12072 1365 TAD [SETDWR] ; assert DIOW 7523 12073 6477 PWCR ; ... 7524 12074 1364 TAD [CLRDWR] ; and then clear it 7525 12075 6477 PWCR ; ... 7526 7527 ; We always leave our side of the PPI data bus (e.g. ports A and B) in 7528 ; input mode to avoid any accidental contention should the drive decide it 7529 ; wants to output data for some unknown reason. 7530 12076 1363 TAD [IDEINP] ; set ports A and B to input mode 7531 12077 6477 PWCR ; ... (but C is still an output) 7532 12100 5661 JMP @IDEWRR ; that's it! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 187 Read IDE Register BTS6120.plx 7533 .TITLE Read IDE Register 7534 7535 7536 ; This routine will read one IDE drive register and return the value in the 7537 ; AC. all IDE registers, with the exception of the data register, are always 7538 ; eight bits wide so there's no need to worry about the upper byte here. We 7539 ; simply ignore it. The address of the register to be read should be passed 7540 ; inline, following the call to this procedure. 7541 ; 7542 ;CALL 7543 ; JMS IDERDR 7544 ; xxxx ; IDE register number, including CS1Fx and CS3Fx bits 7545 ; 7546 ; 7547 12101 0000 IDERDR: 0 ; CALL HERE WITH A JMS!! 7548 12102 7200 CLA ; just in case... 7549 12103 1363 TAD [IDEINP] ; set ports A and B to input 7550 12104 6477 PWCR ; ... (this should be unnecessary, 7551 12105 1701 TAD @IDERDR ; get the IDE register address 7552 12106 2301 ISZ IDERDR ; (and don't forget to skip it!) 7553 12107 6476 PWPC ; send it to the drive via port C 7554 12110 1373 TAD [SETDRD] ; assert DIOR 7555 12111 6477 PWCR ; ... 7556 12112 7000 NOP ; give the drive and 8255 time to settle 7557 12113 6471 PRPB ; capture D0..D7 7558 12114 0362 AND [377] ; make sure we don't get noise in DX0..DX3 7559 12115 3322 DCA IDETMP ; and save that for a minute 7560 12116 1361 TAD [CLRDRD] ; now deassert DIOR 7561 12117 6477 PWCR ; ... 7562 12120 1322 TAD IDETMP ; get the data back 7563 12121 5701 JMP @IDERDR ; and return it in the AC 7564 7565 ; Local storage for RD/IDEWRR... 7566 12122 IDETMP: .BLOCK 1 ; a temporary for saving the AC 7567 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 188 Setup Disk I/O Buffer BTS6120.plx 7568 .TITLE Setup Disk I/O Buffer 7569 7570 7571 ; This routine is used parse the argument list for ROM calls that take OS/8 7572 ; handler like argument lists, primarily the RAM disk and IDE disk I/O calls. 7573 ; It will do a GETARG and store the first argument, which contains the R/W 7574 ; bit, page count, buffer field and unit number, in MUUO. It extracts the 7575 ; buffer field from this argument, builds a CDF instruction, and stores that 7576 ; at BUFCDF for later use. It also extracts the page count from this 7577 ; argument, converts it to a negative number, and stores the result at RWCNT. 7578 ; Finally, it does another GETARG to fetch the address of the caller's buffer 7579 ; and stores that at BUFPTR. 7580 12123 6205 SETBUF: .PUSHJ @[GETARG] ; get the first argument 12124 5777 7581 12125 3047 DCA MUUO ; save that - it's got lots of useful bits! 7582 12126 1047 TAD MUUO ; get the field bits from MUUO 7583 12127 0360 AND [70] ; ... 7584 12130 1357 TAD [CDF 0] ; make a CDF instruction out of them 7585 12131 3756 DCA @[BUFCDF+1] ; and save them for later 7586 12132 1047 TAD MUUO ; get the page count from the call 7587 12133 0355 AND [3700] ; ... 7588 12134 7450 SNA ; is it zero ? 7589 12135 7330 NL4000 ; yes - that means to transfer a full 32 pages 7590 12136 7002 BSW ; right justify the page count 7591 12137 7041 CIA ; make it negative for an ISZ 7592 12140 3054 DCA RWCNT ; ... 7593 12141 6205 .PUSHJ @[GETARG] ; get the buffer pointer from the argument list 12142 5777 7594 12143 1354 TAD [-1] ; correct for pre-incrementing auto-index 7595 12144 3011 DCA BUFPTR ; and save that 7596 12145 3052 DCA BUFPNL ; this buffer is always in main memory 7597 12146 6225 .POPJ ; all done for now 7598 12154 7777 12155 3700 12156 2212 12157 6201 12160 0070 12161 0006 12162 0377 12163 0222 12164 0010 12165 0011 12166 0200 12167 7600 12170 7400 12171 1244 12172 7750 12173 0007 12174 2123 12175 0017 12176 7770 12177 0241 7599 12200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 189 Setup Disk I/O Buffer Field and Space BTS6120.plx 7600 .TITLE Setup Disk I/O Buffer Field and Space 7601 7602 7603 ; This routine will set up BUFPTR, BUFCDF, RWCNT and BUFPNL to point to 7604 ; our own internal buffer in panel memory at DSKBUF. This is used by the 7605 ; disk dump, disk load, format and boot commands when they need to read or 7606 ; write disk blocks without distrubing main memory. 7607 12200 1377 PNLBUF: TAD [DSKBUF-1] ; point to the disk buffer 7608 12201 3011 DCA BUFPTR ; set the buffer address for DISKRD/DISKWR 7609 12202 1376 TAD [CDF 1] ; this buffer lives in our field 1 7610 12203 3212 DCA BUFCDF+1 ; ... 7611 12204 7344 NLM2 ; the buffer size is always 2 pages 7612 12205 3054 DCA RWCNT ; ... 7613 12206 7240 NL7777 ; write this data to PANEL memory! 7614 12207 3052 DCA BUFPNL ; ... 7615 12210 6225 .POPJ ; and we're done 7616 7617 7618 ; This little routine is called, via a JMS instruction (not a .PUSHJ!) to 7619 ; change the DF to the field of the user's buffer. In addition, if the 7620 ; BUFPNL flag is not set, it will execute a CPD instruction so that buffer 7621 ; data is stored in main memory. This is the usual case. 7622 12211 0000 BUFCDF: 0 ; call here with a JMS 7623 12212 7000 NOP ; gets over written with a CDF instruction 7624 12213 7200 CLA ; just in case 7625 12214 1052 TAD BUFPNL ; is the panel buffer flag set? 7626 12215 7650 SNA CLA ; ??? 7627 12216 6266 CPD ; no - address main memory now 7628 12217 5611 JMP @BUFCDF ; ... 7629 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 190 Copy Memory ROM Calls BTS6120.plx 7630 .TITLE Copy Memory ROM Calls 7631 7632 7633 ; This ROM function can copy up to 4096 words from any field in either main 7634 ; or panel memory to any other address and field in either main or panel 7635 ; memory. It can be used to move data and/or code into panel memory and 7636 ; back again, or simply to move one part of main memory to another. 7637 ; 7638 ;CALL: 7639 ; PR0 7640 ; 0010 / copy memory subfunction 7641 ; p0n0 / source field and memory space 7642 ;
/ source address 7643 ; p0n0 / destination field and memory space 7644 ;
/ destination address 7645 ; / number of words to be transferred 7646 ; 7647 ; The source and destination field words each contain the field number in 7648 ; bits 6..8, and a flag in bit 0 which is one for panel memory and zero for 7649 ; main memory. The last word of the argument list is the number of words 7650 ; to be copied - a value of zero copies 4096 words. 7651 7652 ; Set up the source address... 7653 12220 6205 MEMMOV: .PUSHJ @[GETARG] ; get the source field 12221 5775 7654 12222 7100 CLL ; make sure the link is in a known state 7655 12223 1374 TAD [4000] ; put the panel/main memory flag in the LINK 7656 12224 0373 AND [70] ; make a CDF instruction 7657 12225 1372 TAD [CDF 0] ; ... 7658 12226 3262 DCA SRCCDF ; ... 7659 12227 1371 TAD [CPD] ; assume the source is in main memory 7660 12230 7430 SZL ; but is it really ? 7661 12231 1370 TAD [SPD-CPD] ; no - use panel memory 7662 12232 3263 DCA SRCSPD ; ... 7663 12233 6205 .PUSHJ @[GETARG] ; get the buffer address 12234 5775 7664 12235 1367 TAD [-1] ; correct for pre-increment auto index 7665 12236 3012 DCA XX1 ; ... 7666 7667 ; Set up the destination address... 7668 12237 6205 .PUSHJ @[GETARG] ; get the destination field 12240 5775 7669 12241 7100 CLL ; make sure the link is in a known state 7670 12242 1374 TAD [4000] ; put the panel/main memory flag in the LINK 7671 12243 0373 AND [70] ; make a CDF instruction 7672 12244 1372 TAD [CDF 0] ; ... 7673 12245 3265 DCA DSTCDF ; ... 7674 12246 1371 TAD [CPD] ; assume the destination is in main memory 7675 12247 7430 SZL ; but is it really ? 7676 12250 1370 TAD [SPD-CPD] ; no - use panel memory 7677 12251 3266 DCA DSTSPD ; ... 7678 12252 6205 .PUSHJ @[GETARG] ; get the buffer address 12253 5775 7679 12254 1367 TAD [-1] ; correct for pre-increment auto index 7680 12255 3013 DCA XX2 ; ... 7681 7682 ; And finally the word count... 7683 12256 6205 .PUSHJ @[GETARG] ; ... 12257 5775 7684 12260 7041 CIA ; make it negative for ISZ 7685 12261 3051 DCA XFRCNT ; ... 7686 7687 ; This loop does the actual work of copying data! 7688 12262 7000 SRCCDF: NOP ; over written with a CDF instruction 7689 12263 7000 SRCSPD: NOP ; over written with a SPD/CPD IOT PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 191 Copy Memory ROM Calls BTS6120.plx 7690 12264 1412 TAD @XX1 ; get a word of source data 7691 12265 7000 DSTCDF: NOP ; over written with a CDF instruction 7692 12266 7000 DSTSPD: NOP ; overwritten with a SPD/CPD IOT 7693 12267 3413 DCA @XX2 ; and store the word 7694 12270 2051 ISZ XFRCNT ; have we done them all ? 7695 12271 5262 JMP SRCCDF ; no - keep copying 7696 7697 ; All done! 7698 12272 6276 SPD ; be sure the field and memory space are safe 7699 12273 6211 CDF 1 ; ... 7700 12274 7300 CLL CLA ; and always return success 7701 12275 6225 .POPJ ; ... 7702 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 192 Copy Memory Extended ROM Call BTS6120.plx 7703 .TITLE Copy Memory Extended ROM Call 7704 7705 7706 ; This ROM function can copy up to 4096 words from any field in main, panel 7707 ; or ramdisk memory to any other field in main, panel or ramdisk memory. 7708 ; 7709 ;CALL: 7710 ; PR0 7711 ; 0011 / copy memory subfunction 7712 ; pddf / source DAR, field and memory space 7713 ; pddf / destination DAR, field and memory space 7714 ;
/ source address 7715 ;
/ destination address 7716 ; / number of words to be transferred 7717 ; 7718 ; The source and destination field words (pddf) each contain a flag 7719 ; in bit 0, the ramdisk Disk Address in bits 1..8 (or a flag in bit 1), 7720 ; and the field number in bits 9..11 7721 ; 7722 ; The flags are interpreted as 7723 ; bit 0 = 1 when the address is in the ramdisk, otherwise 7724 ; bit 1 = 1 when the address is in panel memory, otherwise 7725 ; the address is in main memory 7726 ; The last word of the argument list is the number of words 7727 ; to be copied - a value of zero copies 4096 words. 7728 7729 0024 SRCDAR=RDUNIT 7730 0025 DSTDAR=RDPAGE 7731 7732 12276 7200 MEMMVX: CLA ; set up source addressing 7733 12277 1366 TAD [XSRCDF-1] 7734 12300 4765 JMS @[MVXARG] 7735 12301 3024 DCA SRCDAR 7736 7737 12302 1364 TAD [XDSCDF-1] ; set up destination addressing 7738 12303 4765 JMS @[MVXARG] 7739 12304 3025 DCA DSTDAR 7740 7741 12305 6205 .PUSHJ @[GETARG] ; get the source address 12306 5775 7742 12307 1367 TAD [-1] ; correct for pre-increment auto index 7743 12310 3012 DCA XX1 ; ... 7744 7745 12311 6205 .PUSHJ @[GETARG] ; get the destination address 12312 5775 7746 12313 1367 TAD [-1] ; correct for pre-increment auto index 7747 12314 3013 DCA XX2 ; ... 7748 7749 12315 6205 .PUSHJ @[GETARG] ; get the word count 12316 5775 7750 12317 7041 CIA ; make it negative for ISZ 7751 12320 3051 DCA XFRCNT ; ... 7752 7753 12321 7000 XSRCDF: NOP ; overwritten with a CDF instruction 7754 12322 7000 NOP ; overwritten with a SPD/CPD IOT 7755 12323 7000 NOP ; overwritten with a memory map IOT 7756 12324 1024 TAD SRCDAR ; set DAR to source DAR 7757 12325 6410 LDAR ; (leaves AC clr) 7758 12326 1412 TAD @XX1 ; get a word of source data 7759 12327 7421 MQL ; save in MQ 7760 12330 7000 XDSCDF: NOP ; overwritten with a CDF instruction 7761 12331 7000 NOP ; overwritten with a SPD/CPD IOT 7762 12332 7000 NOP ; overwritten by a memory map IOT 7763 12333 1025 TAD DSTDAR ; set DAR to destination DAR 7764 12334 6410 LDAR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 193 Copy Memory Extended ROM Call BTS6120.plx 7765 12335 7521 SWP ; get back source value 7766 12336 3413 DCA @XX2 ; and store the word 7767 12337 2051 ISZ XFRCNT ; have we done them all ? 7768 12340 5321 JMP XSRCDF ; no - keep copying 7769 7770 ; All done! 7771 12341 6402 MM2 ; back to standard map 7772 12342 6276 SPD ; be sure the field and memory space are safe 7773 12343 6211 CDF 1 ; ... 7774 12344 7300 CLL CLA ; and always return success 7775 12345 6225 .POPJ ; ... 7776 12364 2327 12365 2400 12366 2320 12367 7777 12370 0010 12371 6266 12372 6201 12373 0070 12374 4000 12375 0241 12376 6211 12377 7377 7777 12400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 194 Get Arguments for MEMMOV Calls BTS6120.plx 7778 .TITLE Get Arguments for MEMMOV Calls 7779 7780 7781 ; MVXARG: 7782 ; call: JMS MVXARG 7783 ; entry: AC points to CDF x, yPD, MMz sequence location 7784 ; function: get and interpret an addressing control argument, filling out @XX1 7785 ; exit: AC contains DAR value 7786 12400 0000 MVXARG: 0 7787 12401 3012 DCA XX1 ; Save pointer to modified code in auto-incr 7788 12402 6205 .PUSHJ @[GETARG] ; get the source field 12403 5777 7789 12404 7100 CLL ; make sure the link is in a known state 7790 12405 1376 TAD [4000] ; put the ramdisk/RAM flag in the LINK 7791 12406 7420 SNL 7792 12407 5226 JMP ADRPMM ; if b0=0, do panel/main memory addressing 7793 ; address is in ramdisk 7794 7795 12410 7014 ADRRMD: R3L ; rotate first two bits of DAR around to lsbs 7796 12411 7421 MQL ; save it; it has the field in the right position 7797 12412 7701 ACL ; get it back (AC was cleared by MQL) 7798 12413 7002 BSW ; rotate another 6 bits, AC now has DAR in b4..b11 7799 12414 7521 SWP ; save it, get back field 7800 12415 0375 AND [70] ; make a CDF instruction 7801 12416 1374 TAD [CDF 0] ; ... 7802 12417 3412 DCA @XX1 ; ... 7803 12420 1373 TAD [SPD] ; ramdisk DF must be panel 7804 12421 3412 DCA @XX1 7805 12422 1372 TAD [MM3] ; use memory map 3 (indirect panel access -> ramdisk) 7806 12423 3412 DCA @XX1 7807 12424 7521 SWP ; and return with DAR in AC 7808 12425 5600 JMP @MVXARG 7809 7810 ; address is in panel or main memory 7811 7812 12426 1371 ADRPMM: TAD [6000] ; know that b0=0, link=1; 7813 ; now link=0 if b1=1 7814 12427 7014 R3L ; bring field into position 7815 12430 0375 AND [70] ; make a CDF instruction 7816 12431 1374 TAD [CDF 0] ; ... 7817 12432 3412 DCA @XX1 ; ... 7818 12433 1370 TAD [CPD] ; assume the source is in main memory 7819 12434 7420 SNL ; but is it really ? 7820 12435 1367 TAD [SPD-CPD] ; no - use panel memory 7821 12436 3412 DCA @XX1 ; ... 7822 12437 1366 TAD [MM2] ; use memory map 2 (indirect access -> RAM) 7823 12440 3412 DCA @XX1 7824 12441 5600 JMP @MVXARG PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 195 LIGHTS Monitor Call BTS6120.plx 7825 .TITLE LIGHTS Monitor Call 7826 7827 7828 ; The LIGHTS MUUO allows a program explicit control over the front panel 7829 ; DATA LEDs (providing a front panel is installed, of course!). It only 7830 ; works for the DATA LEDs - the ADDRESS LEDs always track the current memory 7831 ; address, and it only works _if_ the rotary switch is _not_ set to the MD 7832 ; position. 7833 ; 7834 ; The calling sequence for the LIGHTS MUUO is: 7835 ; 7836 ; TAD (data / desired data for the display 7837 ; PR0 / trap to panel memory 7838 ; 0012 / LIGHTS function code 7839 ; / 1 to put the DATA display under program control 7840 ; / 0 to return the display to normal use 7841 ; / if no display is present or is not 0 or 1, 7842 ; / then the LINK will be set on return. 7843 ; 7844 ; Note that a program can determine whether an FP6120 is present without 7845 ; changing anything simply by invoking the LIGHTS function with set 7846 ; to 0. If no display is present, the LINK will be set on return. 7847 ; 7848 12442 6205 LIGHTS: .PUSHJ @[GETARG] ; get the argument 12443 5777 7849 12444 6201 CDF 0 ; FP data lives in field zero 7850 12445 3765 DCA @[FPPGMM] ; set the FP program mode flag 7851 12446 1764 TAD @[UAC] ; and get the user's display data 7852 12447 3763 DCA @[FPPGMD] ; store that too 7853 7854 ; Note that we went ahead and set FPPGMM/FPPGMD even though we don't yet 7855 ; know whether the front panel is isntalled or not. That's harmless enough - 7856 ; these values are never used if the front panel is not present! 7857 12450 1762 TAD @[FPDTCT] ; is a front panel installed?? 7858 12451 6211 CDF 1 ; (back to our field) 7859 12452 7100 CLL ; assume the FP is present 7860 12453 7650 SNA CLA ; and skip if we're right 7861 12454 7020 CML ; nope - return with the link set 7862 12455 6225 .POPJ ; and that's all! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 196 Read Flash ROM Call BTS6120.plx 7863 .TITLE Read Flash ROM Call 7864 7865 7866 ; The Read Flash ROM call reads the last 384K bytes of the IOB6120 7867 ; flash ROM in twelve bit word mode. It's essentially the same as the 7868 ; RAM disk read function and for practical purposes treats the flash ROM 7869 ; as a read only RAM disk. 7870 ; 7871 ; The calling sequence for the PR0 Read Flash ROM call is: 7872 ; 7873 ; PR0 7874 ; 0016 / panel function code for read flash ROM 7875 ; / page count, buffer field 7876 ; / buffer address 7877 ; / starting page number (not block number!) 7878 ; / AC == 0 if success; AC != 0 if error 7879 ; 7880 ; The error return is taken if a) the Write bit is set in the function 7881 ; word (arg 1), or if b) the unit number in the unction word is not zero, 7882 ; or c) the page number is greater than 2016. 7883 ; 7884 ; One might reasonably question whether this code belongs here or in 7885 ; IOB6120 - after all, it's completely useless unless an IOB is installed. 7886 ; The answer is that of course it belongs in the IOB6120 code, but it 7887 ; shares so many routines with RAMDRW that it would have required another 7888 ; dozen or so vectors to make it work. It's easier just to give up a few 7889 ; more words of BTS6120 code space to handle it. 7890 12456 6205 RDROM: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 12457 5761 7891 12460 6205 .PUSHJ @[GETARG] ; and lastly get the disk page number 12461 5777 7892 7893 ; The first 128K bytes of the flash are used to hold the IOB6120 code and 7894 ; the FPGA bitstream, and actual ROM disk data doesn't start until bank 32. 7895 ; There are a couple of ways to handle this, but the easiest is to offset 7896 ; the starting page number by 32*21=672 pages. 7897 12462 1360 TAD [672.] ; offset the ROM disk addresses 7898 12463 3025 DCA RDPAGE ; ... 7899 7900 ; Make sure that an IOB6120 is installed in the first place... 7901 12464 6201 CDF 0 ; the EXTFLAG lives in field 0 7902 12465 1757 TAD @[EXTFLAG] ; get the IOB6120 status 7903 12466 6211 CDF 1 ; ... 7904 12467 7650 SNA CLA ; is there one? 7905 12470 5756 JMP @[RAMER1] ; no - give the "bad unit" return 7906 7907 ; Make sure that the unit number is zero and that the R/W bit is clear 7908 ; (for reading). Take the error return if not. 7909 12471 1047 TAD MUUO ; get the function word 7910 12472 0355 AND [4007] ; these bits must be zero! 7911 12473 7640 SZA CLA ; skip if error 7912 12474 5756 JMP @[RAMER1] ; no - take the "bad unit" return 7913 7914 ; Note that we never call RAMSEL here to select the RAM disk unit, so we 7915 ; must ensure that a) the RAMCDF gets set up correctly (CDF 1 for the flash), 7916 ; and b) the RAMUSZ parameter gets set to the size of this RAM disk unit. 7917 ; The size would be 384K / 4K = 96 banks * 21 pages per bank = 2016 pages, 7918 ; EXCEPT that we've already offset the starting page by 672 and so the 7919 ; size has to be offset too, giving 2688 pages. Not coincidentally, that's 7920 ; exactly the same size as a regular 512K SRAM RAM disk unit! 7921 12475 1354 TAD [CDF 1] ; flash is always selected by field 1 7922 12476 3753 DCA @[RAMCDF+1] ; initialize the RAMcdf routine 7923 12477 1352 TAD [-2688.] ; and set the size of this unit 7924 12500 3045 DCA RAMUSZ ; ... 7925 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 197 Read Flash ROM Call BTS6120.plx 7926 ; Read pages until we're done... 7927 12501 6205 ROMR1: .PUSHJ @[SETDAR] ; calculate the RAM disk address and bank 12502 5751 7928 12503 7630 SZL CLA ; was the page number valid? 7929 12504 5750 JMP @[RAMER2] ; nope - give the bad page error return 7930 12505 6205 .PUSHJ @[UNPACK] ; transfer a page from RAM disk to memory 12506 5747 7931 12507 2025 ISZ RDPAGE ; if we need more, continue on the next page 7932 12510 2054 ISZ RWCNT ; have we done enough pages? 7933 12511 5301 JMP ROMR1 ; nope - keep going 7934 12512 7300 CLA CLL ; all done - return status code 0 (no errors) 7935 12513 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 198 Field 1 Vector Table BTS6120.plx 7936 .TITLE Field 1 Vector Table 7937 7938 7939 12514 6223 RET1F2: CXF 2 ; return to field 2 7940 12515 6225 .POPJ ; the address is already on the stack 7941 7942 12516 6233 RET1F3: CXF 3 ; return to field 3 7943 12517 6225 .POPJ ; the address is already on the stack 7944 7945 7946 ; variable and functions that we may want to access or hook in this field 7947 ; codes: I=instruction pointer, V=variable, H=hook (CIF n, JMP @.+1, V) 7948 ; Add only to the *end* of this list, please! 7949 ; n.b. JMS linkage functions generally cannot be used here 7950 12520 F1VECTOR: 7951 12520 2516 RET1F3 ; I utility - return to field 2 (must be first) 7952 12521 0261 FUNTBL ; V table of ROM functions 7953 12522 3200 CMDTBL ; V table of monitor commands 7954 12523 1213 DISKRD-1 ; H read IDE 7955 12524 1243 DISKWR-1 ; H write IDE 7956 12525 0000 0 7957 12526 0020 DKPART ; V partition number for DISKRD/WR 7958 12527 0021 DKRBN ; V block number for DISKRD/WR 7959 12530 0011 BUFPTR ; V offset for DISKRD/WR 7960 12531 2212 BUFCDF+1 ; V field for DISKRD/WR 7961 12532 0052 BUFPNL ; V memory space for DISKRD/WR 7962 12533 0022 DKSIZE ; V size of IDE attached drive, or 0 if none 7963 12547 0436 12550 0433 12551 0654 12552 2600 12553 0745 12554 6211 12555 4007 12556 0431 12557 0033 12560 1240 12561 2123 12562 0056 12563 0062 12564 0001 12565 0061 12566 6402 12567 0010 12570 6266 12571 6000 12572 6403 12573 6276 12574 6201 12575 0070 12576 4000 12577 0241 7964 12600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 199 Flash ROM erasure and writing BTS6120.plx 7965 .TITLE Flash ROM erasure and writing 7966 7967 7968 ; write block to Flash ROM. Since Flash requires an erasure step, and we 7969 ; don't know how big the file will be, a slightly risky heuristic is used 7970 ; to determine when to issue an erase command. What it does is, whenever the 7971 ; current address is on a 4KB boundary, the next 4KB is scanned. If any bytes 7972 ; there are not 377, an erase command is issued. 4KB is convenient not just 7973 ; because of the PDP-8 pointer size, but because most if not all flash ROMs 7974 ; allocate blocks in multiples of this size (note that in a device blocks 7975 ; may vary in size). 7976 ; 7977 ; There are simple cases that will confuse this, but we will just have to 7978 ; specify that no 4KB block should be filled with 377s in a download image. 7979 ; 7980 ; The incoming data file must be in the Flash download format: 7981 ; byte data 7982 ; 256 words per block (therefore 256 bytes) 7983 ; starting at 0000 with monotonically increasing block numbers 7984 ; 7985 7986 ; N.b. there're a number of places in this routine where the fact that 7987 ; the ROM is in field 1 of the ramdisk memory while this code is in 7988 ; field 1 of the RAM is taken advantage of. 7989 7990 12600 3053 ROMWR: DCA BUFSIZ ; save the passed size (= -256) 7991 7992 12601 1021 TAD DKRBN ; DAR is set to the upper 8 bits of the 7993 12602 7012 RTR ; block number 7994 12603 7012 RTR 7995 12604 6410 LDAR 7996 7997 12605 6403 MM3 ; access the ramdisk area 7998 7999 12606 1377 TAD [FCMDCS] ; issue "clear status register" command 8000 12607 3400 DCA @0 8001 12610 1376 TAD [FCMDRA] ; issue "read array" command 8002 12611 3400 DCA @0 8003 8004 12612 1021 TAD DKRBN 8005 12613 0375 AND [17] ; check for multiple of 4KB (16*256) 8006 12614 7640 SZA CLA 8007 12615 5246 JMP NOERA 8008 8009 ; We're on a 4KB boundary, check the next 4KB for non-377 bytes 8010 8011 12616 3341 DCA NX1 ; starting at 0 8012 12617 1741 CHKERA: TAD @NX1 8013 12620 1374 TAD [-377] 8014 12621 7640 SZA CLA 8015 12622 5226 JMP ERABLK ; need to erase 8016 12623 2341 ISZ NX1 8017 12624 5217 JMP CHKERA 8018 12625 5246 JMP NOERA 8019 8020 ; Erase block. We don't know how far this erase will extend, but we will 8021 ; only erase again when we reach some unerased ROM, so it's not an issue. 8022 8023 12626 1373 ERABLK: TAD [FCMDERA1] ; issue "erase block 1" command 8024 12627 3400 DCA @0 8025 12630 1372 TAD [FCMDERA2] ; issue "erase block 2" command 8026 12631 3400 DCA @0 8027 12632 7200 WFRDY1: CLA ; get the status byte 8028 12633 1400 TAD @0 8029 12634 0371 AND [200] ; check the ready bit PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 200 Flash ROM erasure and writing BTS6120.plx 8030 12635 7450 SNA 8031 12636 5232 JMP WFRDY1 ; no, not ready yet 8032 12637 7200 CLA 8033 12640 1400 TAD @0 ; get the status again to check for errors 8034 12641 0370 AND [177] 8035 12642 7450 SNA 8036 12643 5246 JMP NOERA 8037 12644 1367 TAD [1000] ; Error 1xxx - bad erase; xxx is status code 8038 12645 5336 JMP BADFL 8039 8040 ; now program the block 8041 8042 12646 1021 NOERA: TAD DKRBN ; form the offset by taking the lower 4 8043 12647 7002 BSW ; bits of the block number and using that 8044 12650 7006 RTL ; to address a 256-byte sector 8045 12651 0366 AND [7400] 8046 12652 3341 DCA NX1 ; destination address 8047 8048 12653 1365 TAD [DSKBUF-1] ; source buffer (field 1) 8049 12654 3012 DCA XX1 ; save in autoincr 8050 8051 12655 6403 PROGLP: MM3 8052 12656 1364 TAD [FCMDPROG] ; issue the write byte command 8053 12657 3741 DCA @NX1 8054 12660 6402 MM2 8055 12661 1412 TAD @XX1 8056 12662 6403 MM3 8057 12663 3741 DCA @NX1 ; and write it 8058 8059 12664 7200 WFRDY2: CLA ; get the status byte 8060 12665 1400 TAD @0 8061 12666 0371 AND [200] ; check the ready bit 8062 12667 7450 SNA 8063 12670 5264 JMP WFRDY2 ; no, not ready yet 8064 12671 7200 CLA 8065 12672 1400 TAD @0 ; b8=1, b6-b0=status bits 8066 12673 0370 AND [177] 8067 12674 7450 SNA 8068 12675 5300 JMP FLNXT 8069 12676 1363 TAD [2000] ; Error 2xxx - bad write; xxx is status code 8070 12677 5336 JMP BADFL 8071 8072 12700 2341 FLNXT: ISZ NX1 ; increment write address 8073 12701 7000 NOP ; may be at end of field 8074 8075 12702 2053 ISZ BUFSIZ ; done with block? 8076 12703 5255 JMP PROGLP ; no, write another byte 8077 8078 12704 1376 TAD [FCMDRA] ; flash back into read array mode 8079 12705 3400 DCA @0 8080 8081 ; now verify the data in ROM against the RAM buffer 8082 8083 12706 1365 TAD [DSKBUF-1] ; compare the disk buffer 8084 12707 3012 DCA XX1 8085 8086 12710 1341 TAD NX1 ; to the ROM, and 8087 12711 1365 TAD [-256.-1] 8088 12712 3013 DCA XX2 8089 8090 12713 1366 TAD [-256.] ; check 256 bytes 8091 12714 3053 DCA BUFSIZ 8092 12715 5316 JMP CHKLP 8093 8094 12716 6402 CHKLP: MM2 ; note that comparison will fail if PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 201 Flash ROM erasure and writing BTS6120.plx 8095 12717 1412 TAD @XX1 ; data in DSKBUF has any of the upper 4 bits 8096 12720 7041 CIA ; set, since the ROM is an 8-bit device 8097 12721 6403 MM3 8098 12722 1413 TAD @XX2 8099 12723 7440 SZA 8100 12724 5332 JMP BADCHK 8101 12725 2053 ISZ BUFSIZ 8102 12726 5316 JMP CHKLP 8103 8104 12727 6402 MM2 8105 12730 7300 CLA CLL 8106 12731 6225 .POPJ 8107 8108 12732 7200 BADCHK: CLA 8109 12733 1013 TAD XX2 8110 12734 0362 AND [0777] ; Error 3xxx - compare mismatch; xxx is offs. 8111 12735 1361 TAD [3000] 8112 8113 12736 6402 BADFL: MM2 8114 12737 7120 STL 8115 12740 6225 .POPJ 8116 8117 ; Flash ROM routine storage.. 8118 12741 NX1: .BLOCK 1 8119 12761 3000 12762 0777 12763 2000 12764 0100 12765 7377 12766 7400 12767 1000 12770 0177 12771 0200 12772 0320 12773 0040 12774 7401 12775 0017 12776 7777 12777 0120 8120 13000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 202 Free Space for Future Expansion! BTS6120.plx 8121 .TITLE Free Space for Future Expansion! 8122 8123 ; space to put any patch code for this field 8124 13000 F1PATCH: 8125 8126 13200 .PAGE 15 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 203 Command Names Table BTS6120.plx 8127 .TITLE Command Names Table 8128 8129 8130 ; This table gives the names of all the commands known to the monitor. Each 8131 ; entry consists of a one or two letter command name, in SIXBIT, followed by 8132 ; the address of a routine to execute it. Although this table is stored in 8133 ; field 1, all the command routines are implicitly in field zero! The zero 8134 ; entry at the end is a "catch all" that is called if none of the previous 8135 ; names match, and points to an error routine. With the exception of this last 8136 ; entry, the order of the table is not significant. 8137 13200 CMDTBL: 8138 13200 .SIXBIT /H / ; Help 8139 13201 0736 HELP ; ... 8140 13202 .SIXBIT /RP/ ; RePeat 8141 13203 0600 REPEAT ; ... 8142 13204 .SIXBIT /E / ; Examine 8143 13205 1002 EMEM ; ... 8144 13206 .SIXBIT /EP/ ; Examine Panel memory 8145 13207 1000 EPMEM ; ... 8146 13210 .SIXBIT /D / ; Deposit 8147 13211 1067 DMEM ; ... 8148 13212 .SIXBIT /DP/ ; Deposit Panel memory 8149 13213 1065 DPMEM ; ... 8150 13214 .SIXBIT /ER/ ; Examine Register 8151 13215 1114 EREG ; ... 8152 13216 .SIXBIT /DR/ ; Deposit Register 8153 13217 1132 DREG ; ... 8154 13220 .SIXBIT /BM/ ; Block Move 8155 13221 1400 BMOVE ; ... 8156 13222 .SIXBIT /CK/ ; ChecKsum 8157 13223 1442 CKMEM ; ... 8158 13224 .SIXBIT /WS/ ; Word Search 8159 13225 1600 SEARCH ; ... 8160 13226 .SIXBIT /CM/ ; Clear Memory 8161 13227 1507 CMEM ; ... 8162 13230 .SIXBIT /FM/ ; Fill Memory 8163 13231 1503 FLMEM ; ... 8164 13232 .SIXBIT /BL/ ; Breakpoint List 8165 13233 1674 BLIST ; ... 8166 13234 .SIXBIT /BP/ ; BreakPoint 8167 13235 2036 BPTCOM ; ... 8168 13236 .SIXBIT /BR/ ; Breakpoint Remove 8169 13237 2000 BREMOV ; ... 8170 13240 .SIXBIT /C / ; Continue 8171 13241 2214 CONTCM ; ... 8172 13242 .SIXBIT /SI/ ; Single Instruction with no trace 8173 13243 2200 SNCOM ; ... 8174 13244 .SIXBIT /ST/ ; STart 8175 13245 2251 START ; ... 8176 13246 .SIXBIT /P / ; Proceed 8177 13247 2207 PROCEE ; ... 8178 13250 .SIXBIT /TR/ ; single instruction with TRace 8179 13251 2144 SICOM ; ... 8180 13252 .SIXBIT /VE/ ; VErsion (of monitor) 8181 13253 0677 VECOM ; ... 8182 13254 .SIXBIT /TW/ ; Terminal Width 8183 13255 0625 TWCOM ; ... 8184 13256 .SIXBIT /TP/ ; Terminal Page 8185 13257 0650 TPCOM ; ... 8186 13260 .SIXBIT /EX/ ; EXECUTE (IOT instruction) 8187 13261 2324 XCTCOM ; ... 8188 13262 .SIXBIT /MR/ ; MASTER RESET 8189 13263 2300 CLRCOM ; ... 8190 13264 .SIXBIT /LP/ ; LOAD PAPER (tape from console) 8191 13265 3200 CONLOD ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 204 Command Names Table BTS6120.plx 8192 13266 .SIXBIT /DD/ ; Disk (IDE) Dump 8193 13267 3405 DDDUMP ; ... 8194 13270 .SIXBIT /RD/ ; Disk (RAM) Dump 8195 13271 3400 RDDUMP ; ... 8196 13272 .SIXBIT /DL/ ; Disk (IDE) Load 8197 13273 3520 DLLOAD ; ... 8198 13274 .SIXBIT /RL/ ; Disk (RAM) Load 8199 13275 3513 RLLOAD ; ... 8200 13276 .SIXBIT /DF/ ; Disk (IDE) Format 8201 13277 3072 DFRMAT ; ... 8202 13300 .SIXBIT /RF/ ; Disk (RAM) Format 8203 13301 3120 RFRMAT 8204 13302 .SIXBIT /B / ; Bootstrap ram disk 8205 13303 2426 BOOT 8206 13304 .SIXBIT /PM/ ; Partition Map 8207 13305 2600 PMEDIT ; ... 8208 13306 .SIXBIT /PC/ ; Partition Copy 8209 13307 4022 PCOPY ; ... 8210 13310 .SIXBIT /FL/ ; Flash Load 8211 13311 4213 FLLOAD 8212 13312 .SIXBIT /PE/ ; Partition Compare 8213 13313 4013 PCOMP ; ... 8214 13314 .SIXBIT /X / ; Disassemble Main Memory 8215 13315 1546 DISASM ; ... 8216 13316 .SIXBIT /XP/ ; Disassemble Panel Memory 8217 13317 1550 DISASMP ; ... 8218 13320 .SIXBIT /SC/ ; SCope 8219 13321 0670 SCCOM 8220 8221 ; there are 9 copies of the end-of-command list sentinel here so that 8222 ; up to 8 commands may be added by an extension ROM 8223 13322 0000 0000 ; This must always be the last entry 8224 13323 0453 COMERR ; Where to go if none of the above matches 8225 13324 0000 0000 ; This must always be the last entry 8226 13325 0453 COMERR ; Where to go if none of the above matches 8227 13326 0000 0000 ; This must always be the last entry 8228 13327 0453 COMERR ; Where to go if none of the above matches 8229 13330 0000 0000 ; This must always be the last entry 8230 13331 0453 COMERR ; Where to go if none of the above matches 8231 13332 0000 0000 ; This must always be the last entry 8232 13333 0453 COMERR ; Where to go if none of the above matches 8233 13334 0000 0000 ; This must always be the last entry 8234 13335 0453 COMERR ; Where to go if none of the above matches 8235 13336 0000 0000 ; This must always be the last entry 8236 13337 0453 COMERR ; Where to go if none of the above matches 8237 13340 0000 0000 ; This must always be the last entry 8238 13341 0453 COMERR ; Where to go if none of the above matches 8239 13342 0000 0000 ; This must always be the last entry 8240 13343 0453 COMERR ; Where to go if none of the above matches PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 205 Argument Tables for Various Commands BTS6120.plx 8241 .TITLE Argument Tables for Various Commands 8242 8243 8244 ; This table gives a list of the legal register names for the ER (Examine 8245 ; Register) command... 8246 13344 ENAMES: .SIXBIT /AC/ ; The AC 8247 13345 1252 TYPEAC 8248 13346 .SIXBIT /PC/ ; The PC 8249 13347 1255 TYPEPC 8250 13350 .SIXBIT /MQ/ ; The MQ 8251 13351 1260 TYPEMQ 8252 13352 .SIXBIT /PS/ ; The processor status 8253 13353 1265 TYPEPS 8254 13354 .SIXBIT /SR/ ; The switch register 8255 13355 1276 TYPESR 8256 13356 0000 0000 ; None of the above 8257 13357 0453 COMERR 8258 8259 ; This table gives a list of the legal register names for the DR (deposit 8260 ; register) command... 8261 13360 DNAMES: .SIXBIT /AC/ ; The AC 8262 13361 1200 DAC 8263 13362 .SIXBIT /PC/ ; The PC 8264 13363 1203 DPC 8265 13364 .SIXBIT /MQ/ ; The MQ 8266 13365 1206 DMQ 8267 13366 .SIXBIT /PS/ ; The flags 8268 13367 1211 DPS 8269 13370 .SIXBIT /SR/ ; The switch register 8270 13371 1221 DSR 8271 13372 0000 0000 ; None of the above 8272 13373 0453 COMERR 8273 8274 ; This table is a list of the arguments to the B (BOOT) command... 8275 13374 BNAMES: .SIXBIT /VM/ ; VMA0 8276 13375 2464 BTVMA0 8277 13376 .SIXBIT /ID/ ; IDA0 8278 13377 2500 BTIDA0 8279 13400 0000 0000 ; end of list 8280 13401 0453 COMERR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 206 Messages BTS6120.plx 8281 .TITLE Messages 8282 8283 ; General purpose messages... 8284 13402 CKSMSG: .TEXT /Checksum = / 8285 13413 MEMMSG: .TEXT /?Memory error at / 8286 13430 ERRILV: .TEXT /Illegal value/ 8287 13442 ERRSRF: .TEXT /Search fails/ 8288 13453 ERRRAN: .TEXT /Wrong order/ 8289 13464 ERRWRP: .TEXT /Wrap around/ 8290 13475 SKPMSG: .TEXT /Skip / 8291 13502 ERRDIO: .TEXT \?I/O Error \ 8292 13513 ERRCKS: .TEXT /Checksum error/ 8293 13526 ERRNBT: .TEXT /No bootstrap/ 8294 13537 ERRNDK: .TEXT /No disk/ 8295 8296 ; Program trap messages... 8297 13545 BPTMSG: .TEXT /%Breakpoint at / 8298 13560 PR0MSG: .TEXT /?Illegal PR0 function at / 8299 13602 BRKMSG: .TEXT /%Break at / 8300 13612 PRNMSG: .TEXT /?Panel trap at / 8301 13625 HLTMSG: .TEXT /?Halted at / 8302 13636 TRPMSG: .TEXT /?Unknown trap at / 8303 8304 ; Breakpoint messages... 8305 13653 ERRNBP: .TEXT /None set/ 8306 13662 ERRNST: .TEXT /Not set/ 8307 13670 ERRAST: .TEXT /Already set/ 8308 13701 ERRBTF: .TEXT /Table full/ 8309 8310 ; Register names... 8311 13711 ACNAME: .TEXT /AC>/ 8312 13714 PCNAME: .TEXT /PC>/ 8313 13717 MQNAME: .TEXT /MQ>/ 8314 13722 IRNAME: .TEXT /IR>/ 8315 13725 SRNAME: .TEXT /SR>/ 8316 13730 PSNAME: .TEXT /PS>/ 8317 13733 SP1NAM: .TEXT /SP1>/ 8318 13737 SP2NAM: .TEXT /SP2>/ 8319 8320 ; Disk formatting status messages... 8321 13743 FCFMSG: .TEXT \Format unit/partition \ 8322 13763 FM1MSG: .TEXT /Writing / 8323 13772 FM2MSG: .TEXT / Verifying / 8324 14003 FM3MSG: .TEXT / Done/ 8325 14010 ERRDSK: .TEXT \?Verification error, block/page \ 8326 8327 ; Partition copy messages.... 8328 14037 CCFMSG: .TEXT \Overwrite partition \ 8329 14056 CP1MSG: .TEXT /Copying / 8330 4003 CP2MSG=FM3MSG 8331 8332 ; Partition compare messages.... 8333 3772 CE1MSG=FM2MSG 8334 4010 CEEMSG=ERRDSK 8335 8336 ; Partition map messages... 8337 14065 PM1MSG: .TEXT /Unit / 8338 14072 PM2MSG: .TEXT / -> Partition / 8339 8340 ; Device names that get printed by the boot sniffer... 8341 14105 VMAMSG: .TEXT /-VMA0/ 8342 14112 IDAMSG: .TEXT /-IDA0/ 8343 8344 ; System name message... 8345 14117 SYSNM1: .TEXT /SBC6120 ROM Monitor V/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 207 Messages BTS6120.plx 8346 14136 SYSNM2: .TEXT / Checksum / 8347 14146 SYSNM3: .TEXT / \d \h/ 8348 14164 SYSCRN: .TEXT /Copyright (C) 1983-2004 Spare Time Gizmos. All rights reserved./ 8349 8350 ; RAM disk status message... 8351 14240 RAMMS1: .TEXT /NVR: / 8352 14245 RAMMS3: .TEXT /KB/ 8353 14250 BOKMSG: .TEXT / - Battery OK/ 8354 14262 BFAMSG: .TEXT / - Battery FAIL/ 8355 8356 ; IDE disk status message... 8357 14275 IDEMS1: .TEXT /IDE: / 8358 14302 IDEMS2: .TEXT /MB - / 8359 14307 IDEMS3: .TEXT /Not detected/ 8360 14320 IDEMS4: .TEXT /Not supported/ 8361 8362 ; Extension ROM messages 8363 14332 XRMES1: .TEXT /ROM: Error / 8364 8365 ; Flash messages 8366 14343 FLMSG1: .TEXT /?No Flash/ 8367 14352 FLMSG2: .TEXT /Overwrite flash/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 208 Help Text BTS6120.plx 8368 .TITLE Help Text 8369 8370 8371 ; This table is used by the HELP command to generate a page of text 8372 ; describing the monitor commands. Each word is a pointer to a text string, 8373 ; also in field 1, which contains a single line of text, usually a description 8374 ; of one command. The table ends with a zero word. 8375 14365 HLPLST: 8376 ; Examine/Deposit commands... 8377 .DATA HLPEDC 14365 4465 8378 .DATA HLPE, HLPEP, HLPER, HLPX, HLPXP 14366 4511 14367 4553 14370 4616 14371 4643 14372 4702 8379 .DATA HLPD, HLPDP, HLPDR 14373 4741 14374 5005 14375 5052 8380 ; Memory commands... 8381 .DATA HLPNUL, HLPMEM 14376 4464 14377 5103 8382 .DATA HLPBM, HLPCK, HLPWS, HLPFM, HLPCM 14400 5116 14401 5153 14402 5210 14403 5247 14404 5301 8383 ; Breakpoint commands... 8384 .DATA HLPNUL, HLPBPC 14405 4464 14406 5330 8385 .DATA HLPBP, HLPBR, HLPBL, HLPP 14407 5346 14410 5372 14411 5421 14412 5443 8386 ; Program control commands... 8387 .DATA HLPNUL, HLPPCC 14413 4464 14414 5471 8388 .DATA HLPST, HLPC, HLPSI, HLPTR, HLPEX, HLPMR 14415 5512 14416 5547 14417 5572 14420 5615 14421 5642 14422 5676 8389 ; Disk commands... 8390 .DATA HLPNUL, HLPDSK 14423 4464 14424 5715 8391 .DATA HLPLP, HLPRD, HLPRL, HLPRF, HLPDD, HLPDL, HLPDF 14425 5727 14426 5754 14427 6011 14430 6035 14431 6060 14432 6117 14433 6145 8392 .DATA HLPPC, HLPPE, HLPFL, HLPPM, HLPB 14434 6235 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 209 Help Text BTS6120.plx 14435 6274 14436 6343 14437 6172 14440 6366 8393 ; Other (miscellaneous) commands... 8394 .DATA HLPNUL, HLPMSC 14441 4464 14442 6416 8395 .DATA HLPTW, HLPTP, HLPSC, HLPVE, HLPSEM, HLPRP, HLPDOL 14443 6436 14444 6465 14445 6520 14446 6553 14447 6600 14450 6641 14451 6703 8396 ; Special control characters... 8397 .DATA HLPNUL, HLPCTL 14452 4464 14453 6730 8398 .DATA HLPCTS, HLPCTQ, HLPCTO, HLPCTC, HLPCTH, HLPRUB, HLPCTR, HLPCTU 14454 6745 14455 7004 14456 7042 14457 7075 14460 7130 14461 7201 14462 7246 14463 7301 8399 HLPNUL: .DATA 0 14464 0000 8400 8401 ; Examine/Deposit commands... 8402 14465 HLPEDC: .TEXT /EXAMINE AND DEPOSIT COMMANDS/ 8403 14511 HLPE: .TEXT /E aaaaa[-bbbbb] [, ccccc]\t-> Examine main memory/ 8404 14553 HLPEP: .TEXT /EP aaaaa[-bbbbb] [, ccccc]\t-> Examine panel memory/ 8405 14616 HLPER: .TEXT /ER [rr]\t\t\t\t-> Examine register/ 8406 14643 HLPX: .TEXT /X aaaaa[-bbbbb]\t\t-> Disassemble main memory/ 8407 14702 HLPXP: .TEXT /XP aaaaa[-bbbbb]\t\t-> Disassemble panel memory/ 8408 14741 HLPD: .TEXT /D aaaaa bbbb, [cccc, ...]\t-> Deposit in main memory/ 8409 15005 HLPDP: .TEXT /DP aaaaa bbbb, [cccc, ...]\t-> Deposit in panel memory/ 8410 15052 HLPDR: .TEXT /DR xx yyyy\t\t\t-> Deposit in register/ 8411 8412 ; Memory commands... 8413 15103 HLPMEM: .TEXT /MEMORY COMMANDS/ 8414 15116 HLPBM: .TEXT /BM aaaaa-bbbbb ddddd\t\t-> Move memory block/ 8415 15153 HLPCK: .TEXT /CK aaaaa-bbbbb\t\t\t-> Checksum memory block/ 8416 15210 HLPWS: .TEXT /WS vvvv [aaaaa-bbbbb [mmmm]]\t-> Search memory/ 8417 15247 HLPFM: .TEXT /FM vvvv [aaaaa-bbbbb]\t\t-> Fill memory/ 8418 15301 HLPCM: .TEXT /CM [aaaaa-bbbbb]\t\t-> Clear memory/ 8419 8420 ; Breakpoint commands... 8421 15330 HLPBPC: .TEXT /BREAKPOINT COMMANDS/ 8422 15346 HLPBP: .TEXT /BP aaaaa\t\t\t-> Set breakpoint/ 8423 15372 HLPBR: .TEXT /BR [aaaaa]\t\t\t-> Remove breakpoint/ 8424 15421 HLPBL: .TEXT /BL\t\t\t\t-> List breakpoints/ 8425 15443 HLPP: .TEXT /P\t\t\t\t-> Proceed past breakpoint/ 8426 8427 ; Program control commands... 8428 15471 HLPPCC: .TEXT /PROGRAM CONTROL COMMANDS/ 8429 15512 HLPST: .TEXT /ST [aaaaa]\t\t\t-> Start main memory program/ 8430 15547 HLPC: .TEXT /C\t\t\t\t-> Continue execution/ 8431 15572 HLPSI: .TEXT /SI\t\t\t\t-> Single instruction/ 8432 15615 HLPTR: .TEXT /TR\t\t\t\t-> Trace one instruction/ 8433 15642 HLPEX: .TEXT /EX 6xxx\t\t\t\t-> Execute an IOT instruction/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 210 Help Text BTS6120.plx 8434 15676 HLPMR: .TEXT /MR\t\t\t\t-> Master reset/ 8435 8436 ; Disk commands... 8437 15715 HLPDSK: .TEXT /DISK COMMANDS/ 8438 15727 HLPLP: .TEXT /LB\t\t\t\t-> Load a BIN paper tape/ 8439 15754 HLPRD: .TEXT /RD u [pppp [cccc]]\t\t-> Dump RAM disk page/ 8440 16011 HLPRL: .TEXT /RL u\t\t\t\t-> Download RAM disk/ 8441 16035 HLPRF: .TEXT /RF u\t\t\t\t-> Format RAM disk/ 8442 16060 HLPDD: .TEXT /DD pppp [bbbb [cccc]]\t\t-> Dump IDE disk block/ 8443 16117 HLPDL: .TEXT /DL pppp\t\t\t\t-> Download IDE disk/ 8444 16145 HLPDF: .TEXT /DF pppp\t\t\t\t-> Format IDE disk/ 8445 16172 HLPPM: .TEXT /PM [u] [pppp]\t\t\t-> Edit or review IDE partition map/ 8446 16235 HLPPC: .TEXT /PC ssss dddd\t\t\t-> Copy partition ssss to dddd/ 8447 16274 HLPPE: .TEXT /PE aaaa bbbb\t\t\t-> Compare (Equal) partition aaaa to bbbb/ 8448 16343 HLPFL: .TEXT /FL\t\t\t\t-> Download Flash ROM/ 8449 16366 HLPB: .TEXT /B [dd]\t\t\t\t-> Boot RAM or IDE disk / 8450 8451 ; Other (miscellaneous) commands... 8452 16416 HLPMSC: .TEXT /MISCELLANEOUS COMMANDS/ 8453 16436 HLPTW: .TEXT /TW nn\t\t\t\t-> Set the console width/ 8454 16465 HLPTP: .TEXT /TP nn\t\t\t\t-> Set the console page length/ 8455 16520 HLPSC: .TEXT /SC n\t\t\t\t-> Set console scope on or off/ 8456 16553 HLPVE: .TEXT /VE\t\t\t\t-> Show firmware version/ 8457 16600 HLPSEM: .TEXT /aa; bb; cc; dd ...\t\t-> Combine multiple commands/ 8458 16641 HLPRP: .TEXT /RP [nn]; A; B; C; ...\t\t-> Repeat commands A, B, C/ 8459 16703 HLPDOL: .TEXT /!any text...\t\t\t-> Comment text/ 8460 8461 ; Special control characters... 8462 16730 HLPCTL: .TEXT /SPECIAL CHARACTERS/ 8463 16745 HLPCTS: .TEXT /Control-S (XOFF)\t\t-> Suspend terminal output/ 8464 17004 HLPCTQ: .TEXT /Control-Q (XON)\t\t\t-> Resume terminal output/ 8465 17042 HLPCTO: .TEXT /Control-O\t\t\t-> Suppress terminal output/ 8466 17075 HLPCTC: .TEXT /Control-C\t\t\t-> Abort current operation/ 8467 17130 HLPCTH: .TEXT /Control-H (Backspace)\t\t-> Delete the last character entered/ 8468 17201 HLPRUB: .TEXT /RUBOUT (Delete)\t\t\t-> Delete the last character entered/ 8469 17246 HLPCTR: .TEXT /Control-R\t\t\t-> Retype the current line/ 8470 17301 HLPCTU: .TEXT /Control-U\t\t\t-> Erase current line/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 211 Temporary Disk Buffer BTS6120.plx 8471 .TITLE Temporary Disk Buffer 8472 8473 8474 ; The last two pages of field 1, addresses 17400 thru 17777, are used as a 8475 ; temporary disk buffer by the disk load, disk dump, disk format and boot 8476 ; commands. 8477 17400 .PAGE 36 8478 17400 DSKBUF: .BLOCK 128. 8479 17600 .PAGE 37 8480 17600 .BLOCK 128. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 212 Field 2 Variables BTS6120.plx 8481 .TITLE Field 2 Variables 8482 8483 8484 20200 .FIELD 2 8485 20000 .PAGE 0 8486 8487 20000 MNEMP: .BLOCK 1 ; address of last mnemonic output 8488 20001 MEA: .BLOCK 1 ; effective address 8489 20002 MIA: .BLOCK 1 ; indirect address 8490 20003 XPC: .BLOCK 1 ; Program Counter 8491 20004 XIR: .BLOCK 1 ; Instruction Register 8492 20005 IFDF: .BLOCK 1 8493 20006 DPNL: .BLOCK 1 8494 8495 20010 .ORG 10 8496 20010 SCAN: .BLOCK 1 ; auto-incr ptr to OPJMP table 8497 20011 ASCAN: .BLOCK 1 ; auto-incr ptr to mnemonic table 8498 20012 MPTR: .BLOCK 1 ; auto-incr ptr for TASZF2 8499 20013 AX1: .BLOCK 1 8500 20014 AX2: .BLOCK 1 8501 8502 20020 .ORG 20 8503 8504 20020 PUSHAC2: .BLOCK 1 8505 20021 DESTA: .BLOCK 1 8506 8507 20100 .ORG 100 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 213 Field 2 Cross Field Linkages BTS6120.plx 8508 .TITLE Field 2 Cross Field Linkages 8509 8510 8511 ; This two routines will allow a routine in field 2 to simulate a .PUSHJ 8512 ; to a routines in field 0 or 1. The contents of the AC are preserved both 8513 ; ways across the call. 8514 ; 8515 ;CALL: 8516 ; JMS PJ0F2 or PJ1F2 ; cross field call "PUSHJ to 0 From 2" 8517 ; ; address of a routine in field 1 8518 ; ; with the AC preserved across the call 8519 ; 8520 20100 0000 PJ0F2: 0 ; call here with a JMS instruction 8521 20101 3020 DCA PUSHAC2 ; save the caller's AC for a minute 8522 20102 6221 CDF 2 8523 20103 1500 TAD @PJ0F2 ; then get caller's argument 8524 20104 3021 DCA DESTA ; that's the address of the routine to call 8525 20105 1100 TAD PJ0F2 ; now get caller's return address 8526 20106 7001 IAC ; and skip over the argument 8527 20107 6215 .PUSH ; put that on the stack 8528 20110 7200 CLA ; (PUSH doesn't clear the AC!) 8529 20111 1177 TAD [RET0F2] ; the field 0 routine will return to 8530 20112 6215 .PUSH ; ... 8531 20113 7200 CLA ; ... 8532 20114 1020 TAD PUSHAC2 ; restore the original AC contents 8533 20115 6203 CXF 0 ; call with IF = DF = 0 8534 20116 5421 JMP @DESTA ; and go to the code in field 0 8535 8536 20117 0000 PJ1F2: 0 ; call here with a JMS instruction 8537 20120 3020 DCA PUSHAC2 ; save the caller's AC for a minute 8538 20121 6221 CDF 2 8539 20122 1517 TAD @PJ1F2 ; then get caller's argument 8540 20123 3021 DCA DESTA ; that's the address of the routine to call 8541 20124 1117 TAD PJ1F2 ; now get caller's return address 8542 20125 7001 IAC ; and skip over the argument 8543 20126 6215 .PUSH ; put that on the stack 8544 20127 7200 CLA ; (PUSH doesn't clear the AC!) 8545 20130 1176 TAD [RET1F2] ; the field 1 routine will return to 8546 20131 6215 .PUSH ; ... 8547 20132 7200 CLA ; ... 8548 20133 1020 TAD PUSHAC2 ; restore the original AC contents 8549 20134 6213 CXF 1 ; call with IF = DF = 1 8550 20135 5421 JMP @DESTA ; and go to the code in field 1 8551 8552 ; This routine is identical to TASCIZ, except that the string is stored in 8553 ; field 2, rather than field 0... 8554 20136 3012 TASZF2: DCA MPTR ; save the pointer to the string 8555 20137 1412 TAD @MPTR ; and get the next character 8556 20140 7450 SNA ; is this the end of the string ?? 8557 20141 6225 .POPJ ; yes -- quit now 8558 20142 4100 JMS PJ0F2 8559 20143 7400 OUTCHR 8560 20144 5137 JMP TASZF2+1 ; and then loop until the end 8561 8562 20176 2514 20177 4302 8563 20200 .ORG 0200 8564 8565 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 8566 ; HEX format) stores a checksum of ROM field 2 in location 20200. This is 8567 ; used by the POST and the VE (version) command. 8568 20200 ROMCK2: .BLOCK 1 8569 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 214 Persistent setting support (NVRAM) BTS6120.plx 8570 .TITLE Persistent setting support (NVRAM) 8571 8572 8573 7700 RDPMLOC = 4032. ; 21*128*1.5 = first free byte in ramdisk 0 DAR 0 8574 ; note: maximum storage is (4096.-4032.-2)/2 words = 31. 8575 0136 RDPMS1 = 0136 ; signature 1 (byte) 8576 0266 RDPMS2 = 0266 ; signature 2 (byte) 8577 8578 20201 7200 RDPSS: CLA 8579 20202 6214 RDF 8580 20203 1377 TAD [CXF 0] 8581 20204 3240 DCA RDPSX 8582 8583 20205 1376 TAD [FIRSTPSS-1] ; set up an auto index register 8584 20206 3013 DCA AX1 ; ... to address the persistent vars 8585 8586 20207 6201 CDF 0 8587 20210 1775 TAD @[RAMBAS] 8588 20211 1374 TAD [RDPMLOC] ; 21*128*1.5 = first free byte in ramdisk field 8589 20212 3014 DCA AX2 ; auto-incr to address NVRAM 8590 8591 20213 6410 LDAR ; set DAR to 0 8592 8593 20214 6403 MM3 ; address the ramdisk memory 8594 ;CDF 0 ; 1st NVRAM 8595 20215 1414 TAD @AX2 ; are the two signature bytes there? 8596 20216 1373 TAD [-RDPMS1] 8597 20217 7640 SZA CLA 8598 20220 5240 JMP RDPSX ; no - exit 8599 20221 1414 TAD @AX2 8600 20222 1372 TAD [-RDPMS2] 8601 20223 7640 SZA CLA 8602 20224 5240 JMP RDPSX ; no - exit 8603 8604 20225 1414 TAD @AX2 ; get the number of words 8605 20226 7041 CIA ; make neg. counter for ISZ 8606 20227 3001 DCA MEA 8607 8608 20230 6403 RDPS0: MM3 8609 ;CDF 0 ; source field 8610 20231 1414 TAD @AX2 ; get the next byte 8611 20232 7002 BSW ; take it as the upper 6 bits 8612 20233 1414 TAD @AX2 ; add in the lower 6 bits 8613 20234 6402 MM2 8614 ;CDF 0 ; destination field 8615 20235 3413 DCA @AX1 ; and store it 8616 20236 2001 ISZ MEA 8617 20237 5230 JMP RDPS0 ; next 8618 8619 20240 0000 RDPSX: 0 8620 20241 6402 MM2 8621 20242 6225 .POPJ 8622 8623 20243 6214 WRPSS: RDF 8624 20244 1377 TAD [CXF 0] 8625 20245 3303 DCA WRPSX 8626 8627 20246 6201 CDF 0 8628 20247 1775 TAD @[RAMBAS] ; starting just after 1st RAM disk page 8629 20250 1374 TAD [RDPMLOC] ; 21*128*1.5 = first free byte in ramdisk field 8630 20251 3014 DCA AX2 ; auto-incr to address NVRAM 8631 8632 20252 1376 TAD [FIRSTPSS-1] ; set up an auto index register 8633 20253 3013 DCA AX1 ; ... to address the persistent vars 8634 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 215 Persistent setting support (NVRAM) BTS6120.plx 8635 20254 6410 LDAR ; set DAR to 0 8636 8637 20255 6403 MM3 ; address the ramdisk memory 8638 ;CDF 0 8639 8640 20256 1371 TAD [RDPMS1] ; store the signature 8641 20257 3414 DCA @AX2 8642 20260 1370 TAD [RDPMS2] 8643 20261 3414 DCA @AX2 8644 8645 20262 1367 TAD [LASTPSS-FIRSTPSS] ; store the number of words written 8646 20263 3414 DCA @AX2 8647 8648 20264 1366 TAD [FIRSTPSS-LASTPSS] ; -number of words to write 8649 20265 3001 DCA MEA 8650 8651 20266 6402 WRPS0: MM2 8652 ;CDF 0 ; source field 8653 20267 1413 TAD @AX1 ; get a word 8654 20270 6403 MM3 8655 ;CDF 0 ; destination field 8656 20271 6215 .PUSH ; save it for splitting 8657 20272 7002 BSW 8658 20273 0365 AND [77] ; get the upper 6 bits in a byte 8659 20274 3414 DCA @AX2 ; save it 8660 20275 6235 .POP 8661 20276 0365 AND [77] ; get the lower 6 bits in a byte 8662 20277 3414 DCA @AX2 ; save it 8663 8664 20300 2001 ISZ MEA 8665 20301 5266 JMP WRPS0 ; next 8666 8667 20302 6402 MM2 8668 8669 20303 0000 WRPSX: 0 8670 20304 6225 .POPJ 8671 20365 0077 20366 7765 20367 0013 20370 0266 20371 0136 20372 7512 20373 7642 20374 7700 20375 0034 20376 0017 20377 6203 8672 20400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 216 Extension ROM management BTS6120.plx 8673 .TITLE Extension ROM management 8674 8675 8676 ; check for an extension ROM in ramdisk memory at 100000000. 8677 ; The check looks for a signature of 'SB' 'C6' at the start, and a valid 8678 ; checksum. 8679 8680 20400 7200 EXTROM: CLA 8681 20401 6201 CDF 0 8682 20402 3777 DCA @[EXTFLAG] ; initialize status to "no extension ROM" 8683 8684 ; Reset the console to the serial port just in case, before 8685 ; the extension ROM is loaded 8686 8687 20403 6412 PRISLU 8688 8689 ; If the extension ROM contains code that prevents the SBC from starting up, 8690 ; there needs to be a way to prevent from being called. So a check is made 8691 ; for an ESC character coming in the serial port, and loading is cancelled 8692 ; if it's found. 8693 8694 20404 6031 KSF ; is there a key in the UART buffer? 8695 20405 5212 JMP EXTRO2 ; no, skip check 8696 20406 6036 KRB ; fetch it 8697 20407 1376 TAD [-33] ; compare to ESC 8698 20410 7450 SNA 8699 20411 5277 JMP NOXROM ; was ESC - abort ROM check 8700 8701 ;*** This section of code downloads the first 4KB of the extension ROM 8702 ;*** into field 3 of RAM. For debugging purposes (using an EPROM emulator), 8703 ;*** or if no extension ROM is installed, this may be commented out so 8704 ;*** that what's currently in field 3 is left alone. Since the initial 8705 ;*** EPROM-to-RAM copy copied field 3, the effect is that field 3 of the 8706 ;*** EPROM is used as the extension ROM code. 8707 ;*** !!! important: also disable the memory check of field 3 !!! 8708 20412 7240 EXTRO2: NL7777 ; point the buffer to offset 0 8709 20413 6211 CDF 1 8710 20414 3775 DCA @[BUFPTR] ; ... 8711 20415 1374 TAD [CDF 3] ; of field 3 8712 20416 3773 DCA @[BUFCDF+1] ; ... 8713 20417 7240 NL7777 8714 20420 3772 DCA @[BUFPNL] ; of panel memory 8715 20421 1371 TAD [CDF 1] 8716 20422 3770 DCA @[RAMCDF+1] ; of RAM disk unit 1 (hopefully a ROM) 8717 20423 7240 NL7777 8718 20424 3767 DCA @[RAMPTR] ; beginning of the memory space 8719 20425 6410 LDAR ; and in the first chunk (DAR=0) 8720 20426 1366 TAD [-21.] ; and we'll do it 21 times, for a full 8721 20427 3002 DCA MIA ; field of 2688 words 8722 20430 4117 UNPLP: JMS PJ1F2 8723 20431 0436 UNPACK ; unpack RAM disk data to the buffer 8724 20432 2002 ISZ MIA 8725 20433 5230 JMP UNPLP 8726 ;*** to here 8727 8728 20434 7240 NL7777 8729 20435 3010 DCA SCAN ; check for the two word signature 8730 20436 6231 CDF 3 8731 20437 1410 TAD @SCAN 8732 20440 1365 TAD [-6342] ; 'SB' 8733 20441 7440 SZA 8734 20442 5277 JMP NOXROM ; nope, not there 8735 20443 1410 TAD @SCAN 8736 20444 1364 TAD [-4326] ; 'C6' 8737 20445 7440 SZA PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 217 Extension ROM management BTS6120.plx 8738 20446 5277 JMP NOXROM ; nope, not there 8739 8740 ; so far so good... checksum it 8741 8742 20447 7240 NL7777 ; starting at beginning of field 8743 20450 3011 DCA ASCAN 8744 20451 1363 TAD [-2688.] ; check the whole downloaded code area 8745 20452 3002 DCA MIA 8746 20453 1411 XRCHECK: TAD @ASCAN ; accumulate checksum 8747 20454 2002 ISZ MIA ; done yet? 8748 20455 5253 JMP XRCHECK ; nope 8749 8750 20456 7450 SNA ; is the checksum 0000? 8751 20457 5262 JMP STARTXROM ; yes, continue the process 8752 8753 20460 7326 NL0002 8754 20461 5275 JMP XROMERR ; no, return error code 0002 8755 8756 ; the extension ROM is present, copied into field 3 and its checksum is valid. 8757 ; Let's call it! 8758 8759 0007 NUMXRARGS=7 ; number of parameters following 8760 8761 20462 STARTXROM: 8762 20462 1362 TAD [NUMXRARGS] 8763 20463 6221 CDF 2 8764 20464 6232 CIF 3 8765 20465 4410 JMS @SCAN 8766 ; parameters passed to Extension ROM entry 8767 20466 0271 VERSION ; BTS6120 ROM version 8768 20467 4306 F0VECTOR ; table of pointers in field 0 8769 20470 4577 F0PATCH-1 ; page that we can use in f0 if needed 8770 20471 2520 F1VECTOR ; table of pointers in field 1 8771 20472 2777 F1PATCH-1 ; page that we can use in f1 if needed 8772 20473 0503 F2VECTOR ; table of pointers in field 1 8773 20474 2377 F2PATCH-1 ; page that we can use in f1 if needed 8774 8775 ; and it returns here with AC=0 for no error, otherwise a code from 0003 up 8776 8777 20475 XROMERR: 8778 20475 6201 CDF 0 8779 20476 3777 DCA @[EXTFLAG] ; save AC as status 8780 20477 6203 NOXROM: CXF 0 8781 20500 6225 .POPJ ; continue initialization process PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 218 Field 2 Vector Table BTS6120.plx 8782 .TITLE Field 2 Vector Table 8783 8784 8785 20501 6233 RET2F3: CXF 3 ; return to field 3 8786 20502 6225 .POPJ ; the address is already on the stack 8787 8788 8789 ; variable and functions that we may want to access or hook in this field 8790 ; codes: I=instruction pointer, V=variable, H=hook (CIF n, JMP @.+1, V) 8791 ; Add only to the *end* of this list, please! 8792 ; n.b. JMS linkage functions generally cannot be used here 8793 20503 F2VECTOR: 8794 20503 0501 RET2F3 ; I utility - return to field 2 (must be first) 8795 20562 0007 20563 2600 20564 3452 20565 1436 20566 7753 20567 0010 20570 0745 20571 6211 20572 0052 20573 2212 20574 6231 20575 0011 20576 7745 20577 0033 8796 20600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 219 X / XP Commands -- Disassemble memory BTS6120.plx 8797 .TITLE X / XP Commands -- Disassemble memory 8798 8799 8800 ; CMDX / CMDXP: the disassembler commands. They share an implementation, 8801 ; since the only difference between them is whether main or panel memory is 8802 ; read. 8803 8804 20600 7200 CMDX: CLA 8805 20601 1377 TAD [CPD] ; access main memory 8806 20602 5205 JMP XCOMM 8807 8808 20603 7200 CMDXP: CLA 8809 20604 1376 TAD [SPD] ; access panel memory 8810 20605 3006 XCOMM: DCA DPNL 8811 8812 20606 4100 JMS PJ0F2 ; get the next command character 8813 20607 6102 SPACMP 8814 8815 20610 7450 SNA ; is it an eol? 8816 20611 5270 JMP DFLTX ; yes, goto special handling 8817 8818 20612 4100 JMS PJ0F2 ; no, throw it back in 8819 20613 6132 BACKUP 8820 8821 20614 4100 JMS PJ0F2 8822 20615 6441 RANGE ; and try getting range from input buffer 8823 8824 20616 6201 DA1L: CDF 0 8825 20617 7300 CLA CLL ; for L/LP commands, assume DF=IF 8826 20620 1775 TAD @[ADRFLD] 8827 20621 7012 RTR 8828 20622 7010 RAR 8829 20623 6215 .PUSH ; save the field for later printing 8830 20624 1775 TAD @[ADRFLD] 8831 20625 3005 DCA IFDF ; the two lower digits of IFDF are the same 8832 8833 20626 1774 TAD @[ADDR] ; get the address from RANGE 8834 20627 3003 DCA XPC 8835 8836 20630 1775 TAD @[ADRFLD] ; get the field from RANGE and make a CDF 8837 20631 1373 TAD [CDF 0] 8838 20632 3235 DCA DAF ; self-modify for memory space and field 8839 20633 1006 TAD DPNL 8840 20634 3236 DCA DAP 8841 20635 0000 DAF: 0 8842 20636 0000 DAP: 0 8843 20637 1403 TAD @XPC ; get the code word at the current address 8844 20640 3004 DCA XIR 8845 20641 6201 CDF 0 8846 20642 6276 SPD 8847 8848 20643 6235 .POP ; get back the field number 8849 20644 6205 .PUSHJ DISA2 ; and disassemble the instruction 20645 5331 8850 8851 20646 6201 CDF 0 8852 20647 7200 CLA ; are we at the end of the range? 8853 20650 1775 TAD @[ADRFLD] ; get the field 8854 20651 7041 CIA ; negate the field 8855 20652 1772 TAD @[HGHFLD] ; compare to the high field 8856 20653 7640 SZA CLA 8857 20654 5262 JMP INCR ; no -- continue 8858 20655 1771 TAD @[HIGH] ; yes -- compare the addresses 8859 20656 7041 CIA ; 8860 20657 1774 TAD @[ADDR] ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 220 X / XP Commands -- Disassemble memory BTS6120.plx 8861 20660 7650 SNA CLA ; are they equal ?? 8862 20661 5310 JMP XCMDDN ; yes -- stop 8863 8864 20662 2774 INCR: ISZ @[ADDR] ; increment address/field 8865 20663 7410 SKP 8866 20664 1370 TAD [10] 8867 20665 1775 TAD @[ADRFLD] 8868 20666 3775 DCA @[ADRFLD] 8869 20667 5216 JMP DA1L 8870 8871 20670 6201 DFLTX: CDF 0 8872 20671 7301 CLL CLA IAC ; AC=0001 L=0 8873 20672 1771 TAD @[HIGH] 8874 20673 3774 DCA @[ADDR] 8875 20674 7430 SZL 8876 20675 1370 TAD [10] 8877 20676 1772 TAD @[HGHFLD] 8878 20677 3775 DCA @[ADRFLD] 8879 20700 7315 CLL CLA IAC R3L ; AC=0010 L=0 8880 20701 1774 TAD @[ADDR] 8881 20702 3771 DCA @[HIGH] 8882 20703 7430 SZL 8883 20704 1370 TAD [10] 8884 20705 1775 TAD @[ADRFLD] 8885 20706 3772 DCA @[HGHFLD] 8886 20707 5216 JMP DA1L 8887 8888 20710 6203 XCMDDN: CXF 0 ; done, 8889 20711 6225 .POPJ ; return to monitor 8890 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 221 Disassemble Current Trace Location BTS6120.plx 8891 .TITLE Disassemble Current Trace Location 8892 8893 8894 ; XTYPIR: prints a disassembly of the current trace location 8895 8896 20712 1767 XTYPIR: TAD @[UIRPC] ; get the current user environment 8897 20713 3003 DCA XPC ; into our local copies 8898 20714 1766 TAD @[UFLAGS] ; [RLA] UFLAGS is in field zero! 8899 20715 3005 DCA IFDF 8900 20716 1765 TAD @[UIR] 8901 20717 3004 DCA XIR 8902 20720 1377 TAD [CPD] ; a TR always happens in main memory (?) 8903 20721 3006 DCA DPNL 8904 8905 20722 1005 TAD IFDF ; get the IF for printing 8906 20723 7012 RTR 8907 20724 7010 RAR 8908 20725 6205 .PUSHJ DISA2 ; and print the line 20726 5331 8909 8910 20727 6203 CXF 0 ; return to TR 8911 20730 6225 .POPJ 8912 8913 ; DISA2: disassemble a line with all the trimmin's. Displays code address, 8914 ; instruction value, and decoded instruction. Enter with AC=field number. 8915 8916 20731 0365 DISA2: AND [7] ; turn field into ASCII 8917 20732 1364 TAD ["0"] 8918 20733 4100 JMS PJ0F2 ; and print it 8919 20734 7400 OUTCHR 8920 20735 1003 TAD XPC ; print the PC 8921 20736 4100 JMS PJ0F2 8922 20737 6322 TOCT4 8923 20740 1363 TAD [DS4MSG-1] ; say "/ " 8924 20741 6205 .PUSHJ TASZF2 20742 5136 8925 20743 1004 TAD XIR ; print the IR (instruction) 8926 20744 4100 JMS PJ0F2 8927 20745 6322 TOCT4 8928 20746 1362 TAD [DS5MSG-1] ; say "\t" 8929 20747 6205 .PUSHJ TASZF2 20750 5136 8930 20751 6221 CDF 2 8931 20752 5761 JMP @[DISA1] ; and print the disassembled line 8932 20761 1000 20762 2277 20763 2274 20764 0060 20765 0007 20766 0002 20767 0006 20770 0010 20771 0040 20772 0042 20773 6201 20774 0035 20775 0036 20776 6276 20777 6266 8933 21000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 222 Disassembler Top Level BTS6120.plx 8934 .TITLE Disassembler Top Level 8935 8936 21000 7200 DISA1: CLA 8937 21001 3000 DCA MNEMP ; no mnemonics output yet 8938 8939 21002 1004 TAD XIR ; get instruction 8940 21003 7002 BSW 8941 21004 7012 RTR ; extract upper digit 8942 21005 0377 AND [16] 8943 21006 1376 TAD [OPJMP-1] ; and make into table ptr 8944 21007 3010 DCA SCAN 8945 8946 21010 1410 TAD @SCAN ; get pointer to mnemonic list for this group 8947 21011 3011 DCA ASCAN ; SCAN now points to post-mnemonic routine (-1) 8948 8949 21012 1004 TAD XIR ; do 1st mnemonic without sentinel check 8950 21013 0411 AND @ASCAN ; so that opcode 0000 works 8951 21014 5221 JMP MAT0B 8952 8953 21015 1004 AMTCH0: TAD XIR ; get instruction 8954 21016 0411 AND @ASCAN ; AND with mask 8955 21017 7450 SNA ; 0 mask at end of list 8956 21020 5252 JMP AMTCH8 ; no more possible matches 8957 21021 7041 MAT0B: CIA 8958 21022 1411 TAD @ASCAN ; compare masked IR with value 8959 21023 7450 SNA 8960 21024 5232 JMP AMTCH2 ; matched! 8961 8962 ; didn't match, skip over variable-length text to next entry 8963 21025 1411 AMTCH1: TAD @ASCAN ; because all strings are odd length 8964 21026 0375 AND [77] ; just look at the even character 8965 21027 7650 SNA CLA ; for termination symbol (00) 8966 21030 5215 JMP AMTCH0 ; yes, end of text, continue searching 8967 21031 5225 JMP AMTCH1 ; no, skip another word 8968 8969 ; did match, output the mnemonic and go back for more (for case of Operate) 8970 21032 1011 AMTCH2: TAD ASCAN ; save the location for later use in OPRGRP 8971 21033 3000 DCA MNEMP 8972 21034 1411 AMTCH3: TAD @ASCAN ; get the packed 6-bit 8973 21035 6215 .PUSH ; save a couple of copies for later use 8974 21036 6215 .PUSH 8975 21037 7002 BSW ; print the first char 8976 21040 6205 .PUSHJ TSIXB 21041 5262 8977 21042 6235 .POP ; print the second char 8978 21043 6205 .PUSHJ TSIXB 21044 5262 8979 21045 6235 .POP 8980 21046 0375 AND [77] ; was it a space? (n.b. space will have printed) 8981 21047 7640 SZA CLA 8982 21050 5234 JMP AMTCH3 ; no, print next two 8983 21051 5215 JMP AMTCH0 ; look for another mnemonic on this line 8984 8985 ; done with mnemonic part of line 8986 21052 1410 AMTCH8: TAD @SCAN ; call post-mnemonic routine for this group 8987 21053 3001 DCA MEA ; (Bad Things seem to happen when you .PUSHJ 8988 21054 6205 .PUSHJ @MEA ; indirect through an auto-increment location) 21055 5401 8989 21056 7200 CLA 8990 21057 4100 JMS PJ0F2 ; print newline 8991 21060 7104 CRLF 8992 21061 6225 .POPJ 8993 8994 21062 0375 TSIXB: AND [77] ; print a single 6bit character 8995 21063 1374 TAD [" "] PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 223 Disassembler Top Level BTS6120.plx 8996 21064 4100 JMS PJ0F2 8997 21065 7400 OUTCHR 8998 21066 6225 .POPJ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 224 Disassemble EA For MRIs BTS6120.plx 8999 .TITLE Disassemble EA For MRIs 9000 9001 9002 ; EAIGRP / EADGRP: post-mnemonic routines for memory reference instructions. 9003 ; prints the effective address (EA) and indirect data values. 9004 9005 21067 1005 EAIGRP: TAD IFDF ; for JMS/JMP, the final destination is in IF 9006 21070 5273 JMP EA2 9007 9008 21071 1005 EADGRP: TAD IFDF ; for AND/TAD/ISZ/DCA, the final value in DF 9009 21072 7114 CLL R3L 9010 21073 0373 EA2: AND [0070] 9011 21074 1372 TAD [CDF 0] ; make into a CDF 9012 21075 3771 DCA @[EA3D] 9013 9014 21076 1005 TAD IFDF ; The initial fetch is always from the IF field 9015 21077 0373 AND [0070] 9016 21100 1372 TAD [CDF 0] ; make into a CDF 9017 21101 3770 DCA @[EA3I] ; and modify the fetch code 9018 9019 21102 1006 TAD DPNL ; get the CPD/SPD and modify the fetch code 9020 21103 3767 DCA @[EA4] 9021 9022 21104 1004 TAD XIR ; get in-page offset from the instruction 9023 21105 0366 AND [177] 9024 21106 7421 MQL ; save it 9025 9026 21107 1004 TAD XIR ; get ZP bit from instruction into Link 9027 21110 7014 R3L 9028 21111 7006 RTL 9029 9030 21112 7200 CLA 9031 21113 1003 TAD XPC ; get current instruction page 9032 21114 0365 AND [7600] 9033 9034 21115 7420 SNL ; test ZP bit in instruction 9035 21116 7200 CLA ; if ZP=0, clear page, otherwise keep PC page 9036 21117 7501 MQA ; combine with offset from instruction 9037 9038 21120 3001 DCA MEA ; now have effective addr 9039 9040 21121 6205 .PUSHJ @[EA3I] ; get value at that address in IF field 21122 5770 9041 21123 3002 DCA MIA 9042 9043 21124 1004 TAD XIR ; get IA bit 9044 21125 7014 R3L 9045 21126 7004 RAL 9046 21127 7620 SNL CLA ; check if IA=0 (not indirect) 9047 21130 5344 JMP EA6 ; yes, do direct directly 9048 9049 21131 1364 TAD [DS2MSG-1] ; Say "@" 9050 21132 6205 .PUSHJ TASZF2 21133 5136 9051 21134 6205 .PUSHJ EA6 ; print " [value]" 21135 5344 9052 21136 1002 TAD MIA ; get double indirect value 9053 21137 3001 DCA MEA 9054 21140 6205 .PUSHJ @[EA3D] ; in correct field (IF if JMP/JMS, else DF) 21141 5771 9055 21142 3002 DCA MIA 9056 21143 5347 JMP EA7 ; print " [value]" and return 9057 9058 21144 1001 EA6: TAD MEA ; print the memory address 9059 21145 4100 JMS PJ0F2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 225 Disassemble EA For MRIs BTS6120.plx 9060 21146 6322 TOCT4 9061 21147 1363 EA7: TAD [DS1MSG-1] ; print the indirect (or double-indirect) 9062 21150 6205 .PUSHJ TASZF2 ; value, in format "\t[xxxx]" 21151 5136 9063 21152 1002 TAD MIA 9064 21153 4100 JMS PJ0F2 9065 21154 6322 TOCT4 9066 21155 1362 TAD [DS6MSG-1] 9067 21156 5136 JMP TASZF2 9068 21162 2301 21163 2265 21164 2270 21165 7600 21166 0177 21167 1227 21170 1224 21171 1226 21172 6201 21173 0070 21174 0040 21175 0077 21176 1377 21177 0016 9069 21200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 226 Disassemble OPR and IOT instructions BTS6120.plx 9070 .TITLE Disassemble OPR and IOT instructions 9071 9072 9073 ; OPRGRP: called to finish up a mnemonic Operate instruction. 9074 ; It checks for instructions that have a parameter and also for unknown 9075 ; opcodes. 9076 9077 21200 7300 OPRGRP: CLA CLL 9078 21201 1000 TAD MNEMP ; get last mnemonic output 9079 21202 7450 SNA ; was there one? 9080 21203 5222 JMP NOMNEM ; no - print "?" and return 9081 21204 1377 TAD [-OP6NOCF] ; was it a CDF/CIF/CXF/PR? 9082 21205 7630 SZL CLA 9083 21206 6225 .POPJ ; no - return w/o printing anything 9084 21207 1004 TAD XIR ; get instruction 9085 21210 7012 RTR ; and extract and print field number 9086 21211 7010 RAR 9087 21212 0376 AND [7] 9088 21213 1375 TAD ["0"] 9089 21214 4100 JMS PJ0F2 9090 21215 7400 OUTCHR 9091 21216 6225 .POPJ 9092 9093 ; IOTGRP: called to finish up a mnemonic IOT instruction 9094 ; Since IOTs are hardware defined, we have only a small standard set 9095 ; of them in the tables; so we see if anything useful was printed and, 9096 ; if not, print a '?' 9097 9098 21217 1000 IOTGRP: TAD MNEMP ; any mnemonics output? 9099 21220 7640 SZA CLA 9100 21221 6225 .POPJ ; yes - return w/o printing anything 9101 21222 1374 NOMNEM: TAD [DS3MSG-1] ; Say "?" 9102 21223 5136 JMP TASZF2 9103 9104 ; EA3: fetch word @MEA in correct memory space and field 9105 ; part of EAxGRP, and modifiied by that code 9106 9107 21224 6201 EA3I: CDF 0 ; in field IF (modifed) 9108 21225 7410 SKP 9109 21226 6201 EA3D: CDF 0 ; in field DF (modified) 9110 21227 6266 EA4: CPD ; main or panel memory (modified) 9111 21230 1401 TAD @MEA ; get value at that address 9112 21231 6221 CDF 2 9113 21232 6276 SPD 9114 21233 6225 .POPJ 9115 9116 21374 2272 21375 0060 21376 0007 21377 6310 9117 21400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 227 Disassembler Tables (MRIs) BTS6120.plx 9118 .TITLE Disassembler Tables (MRIs) 9119 9120 ; Opcode group tables. For each group (upper digit), this 9121 ; table has a mnemonic table pointer and a pointer to a function 9122 ; that prints the parameters (e.g. effective address for AND) 9123 9124 OPJMP: .DATA OP0-1, EADGRP, OP1-1, EADGRP 21400 1417 21401 1071 21402 1423 21403 1071 9125 .DATA OP2-1, EADGRP, OP3-1, EADGRP 21404 1427 21405 1071 21406 1433 21407 1071 9126 .DATA OP4-1, EAIGRP, OP5-1, EAIGRP 21410 1437 21411 1067 21412 1443 21413 1067 9127 .DATA OP6-1, OPRGRP, OP7-1, IOTGRP 21414 1447 21415 1200 21416 1760 21417 1217 9128 9129 ; Mnemonic table. Each entry consists of a mask, a match value, 9130 ; and a text string in sixbit. In order to detect the end of the 9131 ; string, it must be an odd number of characters long so that the 9132 ; last word is xx00. .TEXT could have been used, but 9133 ; it always emits a full word of 0000 and so would have taken more space. 9134 9135 ; the first 6 groups will always match, so no sentinels are necessary 9136 ; The Effective Address will be displayed for these 9137 OP0: .DATA 7000, 0000 21420 7000 21421 0000 9138 21422 .SIXBIT /AND/ 9139 OP1: .DATA 7000, 1000 21424 7000 21425 1000 9140 21426 .SIXBIT /TAD/ 9141 OP2: .DATA 7000, 2000 21430 7000 21431 2000 9142 21432 .SIXBIT /ISZ/ 9143 OP3: .DATA 7000, 3000 21434 7000 21435 3000 9144 21436 .SIXBIT /DCA/ 9145 OP4: .DATA 7000, 4000 21440 7000 21441 4000 9146 21442 .SIXBIT /JMS/ 9147 OP5: .DATA 7000, 5000 21444 7000 21445 5000 9148 21446 .SIXBIT /JMP/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 228 Disassembler Tables (IOTs) BTS6120.plx 9149 .TITLE Disassembler Tables (IOTs) 9150 9151 21450 OP6: ; mnemonics from here to OP6NOCF will have their 3rd digit 9152 .DATA 7707, 6201 ; printed as the parameter 21450 7707 21451 6201 9153 21452 .SIXBIT /CDF/ 9154 .DATA 7707, 6202 21454 7707 21455 6202 9155 21456 .SIXBIT /CIF/ 9156 .DATA 7707, 6203 21460 7707 21461 6203 9157 21462 .SIXBIT /CXF/ 9158 .DATA 7747, 6206 21464 7747 21465 6206 9159 21466 .SIXBIT /PR / 9160 21470 OP6NOCF: 9161 .DATA 7777, 6214 21470 7777 21471 6214 9162 21472 .SIXBIT /RDF/ 9163 .DATA 7777, 6224 21474 7777 21475 6224 9164 21476 .SIXBIT /RIF/ 9165 .DATA 7777, 6234 21500 7777 21501 6234 9166 21502 .SIXBIT /RIB/ 9167 .DATA 7777, 6244 21504 7777 21505 6244 9168 21506 .SIXBIT /RMF/ 9169 .DATA 7777, 6246 21510 7777 21511 6246 9170 21512 .SIXBIT /WSR/ 9171 .DATA 7777, 6256 21514 7777 21515 6256 9172 21516 .SIXBIT /GCF/ 9173 .DATA 7777, 6266 21520 7777 21521 6266 9174 21522 .SIXBIT /CPD/ 9175 .DATA 7777, 6276 21524 7777 21525 6276 9176 21526 .SIXBIT /SPD/ 9177 .DATA 7777, 6205 21530 7777 21531 6205 9178 21532 .SIXBIT /PPC1 / 9179 .DATA 7777, 6245 21535 7777 21536 6245 9180 21537 .SIXBIT /PPC2 / 9181 .DATA 7777, 6215 21542 7777 21543 6215 9182 21544 .SIXBIT /PAC1 / 9183 .DATA 7777, 6255 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 229 Disassembler Tables (IOTs) BTS6120.plx 21547 7777 21550 6255 9184 21551 .SIXBIT /PAC2 / 9185 .DATA 7777, 6225 21554 7777 21555 6225 9186 21556 .SIXBIT /RTN1 / 9187 .DATA 7777, 6265 21561 7777 21562 6265 9188 21563 .SIXBIT /RTN2 / 9189 .DATA 7777, 6235 21566 7777 21567 6235 9190 21570 .SIXBIT /POP1 / 9191 .DATA 7777, 6275 21573 7777 21574 6275 9192 21575 .SIXBIT /POP2 / 9193 .DATA 7777, 6207 21600 7777 21601 6207 9194 21602 .SIXBIT /RSP1 / 9195 .DATA 7777, 6227 21605 7777 21606 6227 9196 21607 .SIXBIT /RSP2 / 9197 .DATA 7777, 6217 21612 7777 21613 6217 9198 21614 .SIXBIT /LSP1 / 9199 .DATA 7777, 6237 21617 7777 21620 6237 9200 21621 .SIXBIT /LSP2 / 9201 .DATA 7777, 6207 21624 7777 21625 6207 9202 21626 .SIXBIT /RSP1 / 9203 9204 .DATA 7777, 6000 21631 7777 21632 6000 9205 21633 .SIXBIT "SKON/PRS " 9206 .DATA 7777, 6001 21640 7777 21641 6001 9207 21642 .SIXBIT /ION/ 9208 .DATA 7777, 6002 21644 7777 21645 6002 9209 21646 .SIXBIT /IOF/ 9210 .DATA 7777, 6003 21650 7777 21651 6003 9211 21652 .SIXBIT "SRQ/PGO" 9212 .DATA 7777, 6004 21656 7777 21657 6004 9213 21660 .SIXBIT "GTF/PEX" 9214 .DATA 7777, 6005 21664 7777 21665 6005 9215 21666 .SIXBIT /RTF/ 9216 .DATA 7777, 6006 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 230 Disassembler Tables (IOTs) BTS6120.plx 21670 7777 21671 6006 9217 21672 .SIXBIT /SGT/ 9218 .DATA 7777, 6007 21674 7777 21675 6007 9219 21676 .SIXBIT /CAF/ 9220 9221 ; console IOTs 9222 .DATA 7777, 6030 21700 7777 21701 6030 9223 21702 .SIXBIT /KCF/ 9224 .DATA 7777, 6031 21704 7777 21705 6031 9225 21706 .SIXBIT /KSF/ 9226 .DATA 7777, 6032 21710 7777 21711 6032 9227 21712 .SIXBIT /KCC/ 9228 .DATA 7777, 6034 21714 7777 21715 6034 9229 21716 .SIXBIT /KRS/ 9230 .DATA 7777, 6035 21720 7777 21721 6035 9231 21722 .SIXBIT /KIE/ 9232 .DATA 7777, 6036 21724 7777 21725 6036 9233 21726 .SIXBIT /KRB/ 9234 .DATA 7777, 6040 21730 7777 21731 6040 9235 21732 .SIXBIT /SPF/ 9236 .DATA 7777, 6041 21734 7777 21735 6041 9237 21736 .SIXBIT /TSF/ 9238 .DATA 7777, 6042 21740 7777 21741 6042 9239 21742 .SIXBIT /TCF/ 9240 .DATA 7777, 6044 21744 7777 21745 6044 9241 21746 .SIXBIT /TPC/ 9242 .DATA 7777, 6045 21750 7777 21751 6045 9243 21752 .SIXBIT /TSK/ 9244 .DATA 7777, 6046 21754 7777 21755 6046 9245 21756 .SIXBIT /TLS/ 9246 21760 0000 0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 231 Disassembler Tables (OPRs) BTS6120.plx 9247 .TITLE Disassembler Tables (OPRs) 9248 9249 21761 OP7: 9250 ; Group 1 9251 GRP1: .DATA 7600, 7200 21761 7600 21762 7200 9252 21763 .SIXBIT /CLA/ 9253 .DATA 7500, 7100 21765 7500 21766 7100 9254 21767 .SIXBIT /CLL/ 9255 .DATA 7440, 7040 21771 7440 21772 7040 9256 21773 .SIXBIT /CMA/ 9257 .DATA 7420, 7020 21775 7420 21776 7020 9258 21777 .SIXBIT /CML/ 9259 .DATA 7401, 7001 22001 7401 22002 7001 9260 22003 .SIXBIT /IAC/ 9261 .DATA 7416, 7002 22005 7416 22006 7002 9262 22007 .SIXBIT /BSW/ 9263 .DATA 7416, 7004 22011 7416 22012 7004 9264 22013 .SIXBIT /RAL/ 9265 .DATA 7416, 7006 22015 7416 22016 7006 9266 22017 .SIXBIT /RTL/ 9267 .DATA 7416, 7010 22021 7416 22022 7010 9268 22023 .SIXBIT /RAR/ 9269 .DATA 7416, 7012 22025 7416 22026 7012 9270 22027 .SIXBIT /RTR/ 9271 .DATA 7416, 7014 22031 7416 22032 7014 9272 22033 .SIXBIT /R3L/ 9273 .DATA 7777, 7000 22035 7777 22036 7000 9274 22037 .SIXBIT /NOP/ 9275 ; Group 1 composite 9276 .DATA 7777, 7240 22041 7777 22042 7240 9277 22043 .SIXBIT /(STA)/ 9278 .DATA 7777, 7041 22046 7777 22047 7041 9279 22050 .SIXBIT /(CIA)/ 9280 .DATA 7777, 7120 22053 7777 22054 7120 9281 22055 .SIXBIT /(STL)/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 232 Disassembler Tables (OPRs) BTS6120.plx 9282 .DATA 7777, 7204 22060 7777 22061 7204 9283 22062 .SIXBIT /(GLK)/ 9284 .DATA 7777, 7300 22065 7777 22066 7300 9285 22067 .SIXBIT /(NL0000) / 9286 .DATA 7777, 7301 22074 7777 22075 7301 9287 22076 .SIXBIT /(NL0001) / 9288 .DATA 7777, 7326 22103 7777 22104 7326 9289 22105 .SIXBIT /(NL0002) / 9290 .DATA 7777, 7325 22112 7777 22113 7325 9291 22114 .SIXBIT /(NL0003) / 9292 .DATA 7777, 7307 22121 7777 22122 7307 9293 22123 .SIXBIT /(NL0004) / 9294 .DATA 7777, 7327 22130 7777 22131 7327 9295 22132 .SIXBIT /(NL0006) / 9296 .DATA 7777, 7340 22137 7777 22140 7340 9297 22141 .SIXBIT /(NLM1) / 9298 .DATA 7777, 7344 22145 7777 22146 7344 9299 22147 .SIXBIT /(NLM2) / 9300 .DATA 7777, 7346 22153 7777 22154 7346 9301 22155 .SIXBIT /(NLM3) / 9302 22161 GRP2: 9303 .DATA 7511, 7500 22161 7511 22162 7500 9304 22163 .SIXBIT /SMA/ 9305 .DATA 7451, 7440 22165 7451 22166 7440 9306 22167 .SIXBIT /SZA/ 9307 .DATA 7431, 7420 22171 7431 22172 7420 9308 22173 .SIXBIT /SNL/ 9309 .DATA 7511, 7510 22175 7511 22176 7510 9310 22177 .SIXBIT /SPA/ 9311 .DATA 7451, 7450 22201 7451 22202 7450 9312 22203 .SIXBIT /SNA/ 9313 .DATA 7431, 7430 22205 7431 22206 7430 9314 22207 .SIXBIT /SZL/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 233 Disassembler Tables (OPRs) BTS6120.plx 9315 .DATA 7601, 7600 22211 7601 22212 7600 9316 22213 .SIXBIT /CLA/ 9317 .DATA 7405, 7404 22215 7405 22216 7404 9318 22217 .SIXBIT /OSR/ 9319 .DATA 7403, 7402 22221 7403 22222 7402 9320 22223 .SIXBIT /HLT/ 9321 .DATA 7777, 7400 22225 7777 22226 7400 9322 22227 .SIXBIT /NOP/ 9323 .DATA 7777, 7410 22231 7777 22232 7410 9324 22233 .SIXBIT /SKP/ 9325 22235 GRP3: 9326 .DATA 7601, 7601 22235 7601 22236 7601 9327 22237 .SIXBIT /CLA/ 9328 .DATA 7501, 7501 22241 7501 22242 7501 9329 22243 .SIXBIT /MQA/ 9330 .DATA 7421, 7421 22245 7421 22246 7421 9331 22247 .SIXBIT /MQL/ 9332 .DATA 7777, 7521 22251 7777 22252 7521 9333 22253 .SIXBIT /SWP/ 9334 .DATA 7777, 7621 22255 7777 22256 7621 9335 22257 .SIXBIT /CAM/ 9336 .DATA 7777, 7701 22261 7777 22262 7701 9337 22263 .SIXBIT /ACL/ 9338 9339 22265 0000 0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 234 Disassembler Messages BTS6120.plx 9340 .TITLE Disassembler Messages 9341 9342 ; Disassembler messages 9343 9344 22266 DS1MSG: .ASCIZ "\t[" 9345 22271 DS2MSG: .ASCIZ "@" 9346 22273 DS3MSG: .ASCIZ "?" 9347 22275 DS4MSG: .ASCIZ "/ " 9348 22300 DS5MSG: .ASCIZ "\t" 9349 22302 DS6MSG: .ASCIZ "]" 9350 9351 22400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 235 Free Space for Future Expansion! BTS6120.plx 9352 .TITLE Free Space for Future Expansion! 9353 9354 ; space to put any patch code for this field 9355 22400 F2PATCH: 9356 9357 .END PALX - Program break is 22400 PALX - No errors detected PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 236 Memory Map BTS6120.plx 00000/ 11111111 11110000 11111111 11111111 11111111 11111111 11111111 11111111 00100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111110 00200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00500/ 11111111 11111111 11110000 00000000 00000000 01111111 11111111 11111111 00600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00700/ 11111111 11111111 11111111 11111111 11111111 11110000 00000111 11111111 01000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01100/ 11111111 11111111 11111111 11111111 11110000 00000000 00001111 11111111 01200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01111111 01400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01500/ 11111111 11111111 11111111 11111111 11111111 11000000 00000000 00011111 01600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01700/ 11111111 11111111 11111111 11111111 11111111 11111111 11110000 00111111 02000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111100 01111111 02200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02300/ 11111111 11111111 11111111 11111111 11111111 11111111 11110000 01111111 02400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02500/ 11111111 11111111 11111111 11111111 11111111 10000000 00000001 11111111 02600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02700/ 11111111 11111111 11111111 11111111 00000000 00000000 00000000 00111111 03000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03100/ 11111111 11111111 11111111 11111111 11111111 11110000 00111111 11111111 03200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03300/ 11111111 11111111 11111111 11111111 11111100 00000000 00000000 01111111 03400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03500/ 11111111 11111111 11111111 11111111 11111111 11111111 00000001 11111111 03600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 237 Memory Map BTS6120.plx 04000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 04100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111001 11111111 04200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 04300/ 11111111 11111111 11111111 11111111 11111100 00000000 00001111 11111111 04400/ 11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000 04500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 04600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 05700/ 11111111 11111111 11111111 11111111 11111111 11111111 10011111 11111111 06000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06100/ 11111111 11111111 11111111 11111100 00000000 00000000 00000000 00001111 06200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06300/ 11111111 11111111 11111111 11111111 11111111 11111111 11000000 11111111 06400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06500/ 11111111 11111111 11111111 11111110 00000000 00000000 00000000 01111111 06600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06700/ 11111111 11111111 11111111 11111111 11111111 11111000 00000000 11111111 07000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07100/ 11111111 11111111 11111111 11111111 11100000 00000001 11111111 11111111 07200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07500/ 11111111 11111111 11111111 11111111 11111111 11111110 01111111 11111111 07600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07700/ 11111111 11111111 11111111 11111111 11111000 00000000 00011111 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 238 Memory Map BTS6120.plx 10000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10100/ 11111111 11111111 11111111 11111111 11111110 00000111 11111111 11111111 10200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10300/ 11111111 11111111 11111111 11111111 11111000 00000011 11111111 11111111 10400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10700/ 11111111 11111111 11111111 11111111 11111110 00000000 01111111 11111111 11000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11100/ 11111111 11111111 11111111 11110000 00000000 00111111 11111111 11111111 11200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11300/ 11111111 11111111 11111111 11111111 11111000 00000000 11111111 11111111 11400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11500/ 11111111 11111111 11111111 11111110 00000000 00111111 11111111 11111111 11600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11700/ 11111111 11111111 11111111 11111111 11111111 11111100 00111111 11111111 12000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 12100/ 11111111 11111111 11111111 11111111 11111110 00001111 11111111 11111111 12200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 12300/ 11111111 11111111 11111111 11111111 11111100 00000000 00001111 11111111 12400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 12500/ 11111111 11111111 11111111 11110000 00000001 11111111 11111111 11111111 12600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 12700/ 11111111 11111111 11111111 11111111 11000000 00000000 01111111 11111111 13000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 239 Memory Map BTS6120.plx 14000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17300/ 11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 17400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 240 Memory Map BTS6120.plx 20000/ 11111110 11111000 11000000 00000000 00000000 00000000 00000000 00000000 20100/ 11111111 11111111 11111111 11111111 11111000 00000000 00000000 00000011 20200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 20300/ 11111000 00000000 00000000 00000000 00000000 00000000 00000111 11111111 20400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 20500/ 11110000 00000000 00000000 00000000 00000000 00000000 00111111 11111111 20600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 20700/ 11111111 11111111 11111111 11111111 11111111 11100000 01111111 11111111 21000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 21100/ 11111111 11111111 11111111 11111111 11111111 11111110 00111111 11111111 21200/ 11111111 11111111 11111111 11110000 00000000 00000000 00000000 00000000 21300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001111 21400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 21500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 21600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 21700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 22000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 22100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 22200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 22300/ 11110000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 22400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 22500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 22600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 22700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 23700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 241 Memory Map BTS6120.plx 24000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 24700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 25700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 26700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 27700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 242 Symbol Table BTS6120.plx .ASCIZ -POP- 2950 9344 9345 9346 9347 9348 9349 .BLOCK -POP- 1202 1379 1380 1381 1382 1383 1384 1385 1386 1390 1391 1392 1393 1399 1400 1401 1402 1407 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1425 1426 1427 1428 1429 1432 1433 1434 1435 1436 1439 1440 1443 1444 1445 1446 1449 1450 1451 1498 1499 1502 1505 1516 1520 1521 1522 1527 2106 2342 2343 3192 3237 3490 3491 3606 3678 3747 3866 4202 4203 4994 5532 5814 5818 5819 5820 5821 5825 5826 5827 5828 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5844 5845 5846 5847 5848 5849 5859 7009 7055 7318 7491 7566 8118 8478 8480 8487 8488 8489 8490 8491 8492 8493 8496 8497 8498 8499 8500 8504 8505 8568 .DATA -POP- 1408 8377 8378 8379 8381 8382 8384 8385 8387 8388 8390 8391 8392 8394 8395 8397 8398 8399 9124 9125 9126 9127 9137 9139 9141 9143 9145 9147 9152 9154 9156 9158 9161 9163 9165 9167 9169 9171 9173 9175 9177 9179 9181 9183 9185 9187 9189 9191 9193 9195 9197 9199 9201 9204 9206 9208 9210 9212 9214 9216 9218 9222 9224 9226 9228 9230 9232 9234 9236 9238 9240 9242 9244 9251 9253 9255 9257 9259 9261 9263 9265 9267 9269 9271 9273 9276 9278 9280 9282 9284 9286 9288 9290 9292 9294 9296 9298 9300 9303 9305 9307 9309 9311 9313 9315 9317 9319 9321 9323 9326 9328 9330 9332 9334 9336 .END -POP- 9357 .FIELD -POP- 961 1196 5802 8484 .HM6120 -POP- 56 .NOWARN -POP- 58 .ORG -POP- 1378 1389 1395 1511 5605 5812 5817 5822 5854 8495 8502 8507 8563 .PAGE -POP- 962 1179 1197 1363 1530 1649 1785 1932 2107 2265 2429 2603 2850 3075 3215 3367 3529 3683 3868 4014 4175 4212 4219 4406 4603 4772 4906 5083 5251 5409 5602 5851 6113 6310 6505 6840 7010 7183 7384 7599 7777 7964 8120 8126 8477 8479 8485 8672 8796 8933 9069 9117 9351 .POP -POP- 4724 5446 5471 5492 5496 8660 8848 8977 8979 .POPJ -POP- 1647 1679 1780 1848 1893 1939 1949 1964 2045 2057 2070 2081 2094 2149 2253 2337 2374 2395 2420 2427 2456 2469 2520 2549 2575 2797 2938 2946 3009 3014 3022 3027 3053 3071 3134 3200 3265 3515 3617 3859 3969 3993 4012 4132 4135 4242 4257 4273 4280 4309 4336 4404 4418 4439 4455 4506 4531 4562 4577 4593 4601 4644 4664 4675 4751 4801 4809 4817 4844 4854 4863 4871 4882 4887 4904 4921 4937 4947 4954 5038 5081 5122 5129 5158 5162 5175 5249 5305 5385 5423 5498 5547 5570 5578 5586 5590 5598 5600 5779 5954 5995 6005 6111 6161 6166 6219 6263 6330 6399 6414 6453 6466 6497 6531 6536 6721 6754 6760 6823 6838 6880 6884 6891 6912 6916 6923 7006 7044 7052 7078 7086 7181 7251 7315 7343 7372 7382 7405 7412 7479 7484 7597 7615 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 243 Symbol Table BTS6120.plx 7701 7775 7862 7935 7940 7943 8106 8115 8557 8621 8670 8781 8786 8889 8911 8992 8998 9083 9091 9100 9114 .PUSH -POP- 4194 4197 4716 5442 5460 5481 8527 8530 8543 8546 8656 8829 8973 8974 .PUSHJ -POP- 1217 1258 1261 1264 1265 1279 1280 1296 1311 1337 1341 1353 1544 1549 1550 1551 1557 1562 1590 1592 1593 1607 1609 1659 1662 1663 1664 1685 1686 1709 1710 1727 1728 1737 1741 1745 1749 1753 1756 1759 1773 1781 1782 1811 1825 1826 1827 1828 1831 1836 1840 1844 1845 1846 1856 1857 1883 1884 1887 1889 1890 1891 1909 1912 1913 1914 1916 1925 1926 1927 1928 1973 1974 1975 1976 1977 1981 1989 2063 2064 2075 2076 2089 2090 2099 2101 2102 2103 2126 2129 2130 2134 2135 2136 2140 2141 2143 2144 2168 2171 2181 2184 2187 2196 2217 2229 2241 2244 2245 2246 2250 2251 2254 2284 2301 2305 2308 2318 2319 2324 2325 2328 2331 2353 2354 2365 2366 2404 2439 2442 2443 2450 2463 2486 2491 2494 2501 2529 2538 2541 2557 2567 2582 2593 2597 2600 2612 2634 2635 2652 2662 2728 2733 2734 2735 2736 2747 2759 2762 2814 2821 2822 2972 2975 2976 2977 2981 2986 2992 2995 3007 3012 3020 3025 3041 3042 3048 3049 3091 3094 3095 3104 3107 3108 3109 3128 3140 3212 3277 3282 3288 3303 3304 3315 3321 3335 3353 3362 3393 3399 3407 3430 3442 3459 3477 3486 3526 3557 3564 3576 3579 3580 3591 3594 3595 3599 3610 3625 3650 3657 3658 3668 3713 3714 3716 3717 3718 3729 3737 3782 3783 3798 3812 3825 3838 3847 3885 3888 3889 3894 3901 3907 3908 3935 3948 3973 3988 3995 4001 4021 4022 4113 4348 4349 4363 4364 4371 4386 4392 4398 4433 4553 4570 4574 4584 4645 4653 4665 4676 4687 4721 4746 4761 4765 4768 4769 4782 4784 4785 4798 4804 4812 4829 4830 4836 4841 4919 4922 4930 4931 5006 5030 5052 5073 5117 5140 5141 5146 5147 5170 5216 5230 5247 5303 5324 5336 5337 5339 5341 5342 5350 5351 5361 5362 5363 5379 5380 5394 5396 5399 5406 5445 5470 5482 5543 5544 5556 5565 5566 5703 5789 5791 5794 5796 5797 5798 5799 5893 5895 5914 6085 6086 6093 6098 6104 6106 6138 6141 6150 6153 6752 6758 6882 6885 6889 6914 6917 6921 6925 7119 7366 7380 7399 7431 7432 7477 7580 7593 7653 7663 7668 7678 7683 7741 7745 7749 7788 7848 7890 7891 7927 7930 8849 8908 8924 8929 8976 8978 8988 9040 9050 9051 9054 9062 .SIXBIT -POP- 8138 8140 8142 8144 8146 8148 8150 8152 8154 8156 8158 8160 8162 8164 8166 8168 8170 8172 8174 8176 8178 8180 8182 8184 8186 8188 8190 8192 8194 8196 8198 8200 8202 8204 8206 8208 8210 8212 8214 8216 8218 8246 8248 8250 8252 8254 8261 8263 8265 8267 8269 8275 8277 9138 9140 9142 9144 9146 9148 9153 9155 9157 9159 9162 9164 9166 9168 9170 9172 9174 9176 9178 9180 9182 9184 9186 9188 9190 9192 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 244 Symbol Table BTS6120.plx 9194 9196 9198 9200 9202 9205 9207 9209 9211 9213 9215 9217 9219 9223 9225 9227 9229 9231 9233 9235 9237 9239 9241 9243 9245 9252 9254 9256 9258 9260 9262 9264 9266 9268 9270 9272 9274 9277 9279 9281 9283 9285 9287 9289 9291 9293 9295 9297 9299 9301 9304 9306 9308 9310 9312 9314 9316 9318 9320 9322 9324 9327 9329 9331 9333 9335 9337 .STACK -POP- 57 .TEXT -POP- 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8297 8298 8299 8300 8301 8302 8305 8306 8307 8308 8311 8312 8313 8314 8315 8316 8317 8318 8321 8322 8323 8324 8325 8328 8329 8337 8338 8341 8342 8345 8346 8347 8348 8351 8352 8353 8354 8357 8358 8359 8360 8363 8366 8367 8402 8403 8404 8405 8406 8407 8408 8409 8410 8413 8414 8415 8416 8417 8418 8421 8422 8423 8424 8425 8428 8429 8430 8431 8432 8433 8434 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8452 8453 8454 8455 8456 8457 8458 8459 8462 8463 8464 8465 8466 8467 8468 8469 8470 .TITLE -POP- 1 59 141 772 853 902 939 1180 1364 1528 1581 1611 1650 1680 1732 1761 1786 1859 1898 1933 1966 2031 2108 2154 2203 2256 2266 2345 2396 2430 2470 2521 2550 2576 2604 2637 2714 2749 2798 2851 2922 2951 3028 3076 3148 3216 3290 3327 3368 3492 3530 3627 3684 3748 3869 4015 4029 4125 4176 4213 4220 4258 4340 4407 4419 4456 4481 4546 4604 4678 4696 4726 4773 4794 4818 4855 4907 4955 4995 5039 5084 5130 5163 5205 5252 5410 5533 5603 5803 5852 5929 5955 5997 6006 6067 6114 6130 6167 6220 6264 6311 6331 6400 6454 6506 6537 6618 6682 6722 6824 6841 6859 6934 6958 7011 7057 7087 7184 7252 7320 7345 7385 7414 7493 7533 7568 7600 7630 7703 7778 7825 7863 7936 7965 8121 8127 8241 8281 8368 8471 8481 8508 8570 8673 8782 8797 8891 8934 8999 9070 9118 9149 9247 9340 9352 .VECTOR -POP- 5618 ACDISP 06072 4516 4534* ACL 7701 4307 4320 6296 6299 7797 ACNAME 13711 1996 2846 8311* ADDR 00035 1411* 1818 1832 2065 2078 2232 2287 2359 2362 2411 2447 2454 2455 2490 2514 2535 2563 2589 3417 3460 3466 3898 3916 3935 4167 4388 4783 4800 4805 4813 4838 4862 4885 4894 4897 8833 8860 8864 8874 8880 ADRFLD 00036 1412* 2040 2233 2288 2361 2416 2518 2537 2565 2587 2739 2742 3418 3476 4168 4391 4781 4807 4815 4840 4864 4870 4878 4900 4903 5116 5128 8826 8830 8836 8853 8867 8868 8878 8884 ADRPMM 12426 7792 7812* ADRRMD 12410 7795* ALPHA 06627 4922 4931 4942* ALPHA1 06635 4945 4950* AMTCH0 21015 8953* 8966 8983 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 245 Symbol Table BTS6120.plx AMTCH1 21025 8963* 8967 AMTCH2 21032 8960 8970* AMTCH3 21034 8972* 8982 AMTCH8 21052 8956 8986* AND 0000 1051 1176 1817 1820 1833 1953 1956 2041 2313 2320 2586 2942 3097 3209 3274 3423 3433 3437 3453 3471 3475 3732 3835 3944 4275 4299 4303 4357 4360 4390 4414 4451 4476 4628 4633 4641 4693 4745 4792 4869 5068 5108 5115 5127 5172 5545 5726 5793 5920 5946 6091 6190 6193 6205 6211 6248 6253 6301 6375 6382 6476 6779 6782 6811 6817 6977 6982 7040 7073 7131 7145 7220 7282 7285 7439 7558 7583 7587 7656 7671 7800 7815 7910 8005 8029 8034 8045 8061 8066 8110 8658 8661 8916 8942 8950 8954 8964 8980 8994 9010 9015 9023 9032 9087 ARGPTR 10050 5845* 5942 5951 ASCAN 20011 8497* 8743 8746 8947 8950 8954 8958 8963 8970 8972 AX1 20013 8499* 8584 8615 8633 8653 AX2 20014 8500* 8589 8595 8599 8604 8610 8612 8630 8641 8643 8646 8659 8662 BACKS1 07141 5244 5248* BACKUP 06132 1470 4155 4598* 8819 BADCHK 12732 8100 8108* BADFL 12736 8038 8070 8113* BADFLR 04262 4081 4096 4104* BADFUN 0237 5961* 5979 5980 5981 5982 5983 5984 BANKSZ 0025 6062* 6424 6433 BATTOK 10032 1300 5835* 6305 6329 6354 6395 BFAMSG 14262 1310 8354* BINCH1 03323 3429 3432 3449 3452 3490* BINCH2 03324 3431 3436 3450 3491* BINLO1 03203 3397* 3402 3487 BINLO2 03205 3399* 3404 BINLO3 03214 3407* 3410 BINLO5 03227 3421* 3462 3467 3479 BINLO6 03276 3455 3465* BINLO7 03301 3425 3470* BINLO8 03314 3447 3473 3482* BLIST 01674 2353* 8165 BLIST1 01701 2358* 2369 BLIST2 01715 2364 2368* BMOVE 01400 2126* 8155 BNAMES 13374 2980 8275* BOKMSG 14250 1307 8353* BOOKEY 02421 2931 2950* BOOT 02426 2972* 8205 BOOT1 02452 2974 2992* 4434 BOOTGO 02445 2986* 2994 2997 BOOTS 00412 1547* 1576 BOOTS0 00416 1550* 1553 BOOTS1 00425 1557* 1570 1580 BOOTS2 00435 1560 1565* BPT 6236 815* 2540 5740 5743 BPTADR 00201 1520* 1523 2386 BPTCL2 02030 2464* 2468 BPTCLR 02026 2441 2463* 4022 BPTCO1 02054 2496 2501* BPTCO2 02056 2502* 2507 BPTCO3 02066 2505 2512* BPTCOM 02036 2486* 8167 BPTDAT 00221 1522* 2390 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 246 Symbol Table BTS6120.plx BPTEND 0210 1523* BPTFLD 00211 1521* 2388 BPTFN1 01741 2407* 2425 BPTFN2 01757 2409 2413 2423* BPTFN3 01760 2418 2424* BPTFND 01737 2404* 2450 2494 BPTIN1 02101 2532* 2548 BPTIN2 02116 2534 2545* BPTIN3 02120 2542 2547* BPTINS 02077 2529* 2662 BPTMSG 13545 5753 8297* BPTRM1 02125 2560* 2574 BPTRM2 02137 2562 2571* BPTRM3 02141 2568 2573* BPTRMV 02123 2557* 5798 BPTTRP 07705 5742 5752* BREMO1 02024 2452 2459* BREMOV 02000 2439* 8169 BRKMSG 13602 5713 8299* BSETUP 01724 2354 2385* 2404 2463 2501 2529 2557 BSW 7002 851 3434 4060 4068 4076 4087 4629 4634 4686 4926 5126 6203 6249 6434 6975 7218 7286 7590 7798 8043 8611 8657 8940 8975 BTIDA0 02500 2995 3018* 8278 BTSTR1 07646 4171 5702 5709* BTSTRP 07636 5670 5688* BTSWCN 00060 1434* 4229 4319 4431 4438 BTVMA0 02464 2992 3005* 8276 BUFCDF 12211 6123 6201 6231 6849 7210 7276 7585 7610 7622* 7628 7960 8712 BUFPNL 10052 5847* 6124 6850 7596 7614 7625 7961 8714 BUFPTR 10011 5819* 6121 6207 6213 6232 6234 6764 6780 6783 6847 7213 7289 7595 7608 7959 8710 BUFSIZ 10053 5848* 6872 6892 6904 6924 7203 7229 7269 7295 7990 8075 8091 8101 BUFTMP 11712 7214 7215 7217 7283 7288 7318* CAF 6007 2776 4454 CAM 7621 3421 CCFMSG 14037 3905 8328* CCPR 6430 803* 2694 4237 CDF 6201 1050 1053 1086 1099 1158 1299 1301 1331 1334 1746 1748 1750 1752 1776 1778 2042 2069 2080 3067 3069 3167 3177 3185 3201 3204 3227 3230 3247 3260 3266 3269 3281 3285 3287 3305 3307 3336 3338 3347 3350 3356 3359 3565 3572 3581 3586 3611 3614 3620 3659 3664 3669 3673 3710 3712 3721 3723 3827 3832 3918 3920 3926 3928 3938 3945 3952 3961 3963 3979 3981 3998 4000 4007 4011 4046 4091 4403 4415 4617 4642 4671 4673 4974 4990 5736 5911 5913 5915 5940 5947 5953 6122 6198 6215 6259 6293 6349 6351 6367 6378 6380 6439 6441 6477 6848 6851 6853 7152 7246 7312 7337 7339 7377 7409 7411 7442 7444 7584 7609 7657 7672 7699 7773 7801 7816 7849 7858 7901 7903 7921 8522 8538 8586 8627 8681 8709 8711 8715 8730 8763 8778 8824 8837 8845 8851 8871 8930 9011 9016 9107 9109 9112 CE1MSG 3772 3896 8333* CEEMSG 4010 8334* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 247 Symbol Table BTS6120.plx CFIELD 01301 2039* 2063 2075 CHBEL 0007 820* 5189 CHBSP 0010 821* 5246 5355 5367 CHCRT 0015 824* 5215 5367 5370 CHCTC 0003 819* 5550 5555 5560 CHCTO 0017 825* 5560 5564 5573 CHCTR 0022 827* 5331 5335 5346 CHCTU 0025 829* 5346 5349 5355 CHDEL 0177 831* CHESC 0033 830* 5373 5378 5435 5447 CHKERA 12617 8012* 8017 CHKHL1 06042 4474 4479* CHKHLT 06031 2657 2674 4470* 4479 4480 CHKLP 12716 8092 8094* 8102 CHKSUM 00046 1420* 2173 2176 2180 2182 2183 2193 2201 3415 3448 3451 3484 3485 3707 3726 3727 3742 3778 3830 3831 3850 3974 3991 CHLFD 0012 823* 5235 5370 5373 CHNUL 0000 818* CHTAB 0011 822* 1626 1628 1629 5429 5435 CHXOF 0023 828* 5573 5581 CHXON 0021 826* 5581 5589 CIA 7041 1168 2091 2314 2410 2415 2939 3249 3483 3597 3800 3814 3849 3990 4078 4093 4099 4276 4884 4980 5225 5466 6297 6491 7591 7684 7750 8096 8605 8854 8859 8957 CIF 6202 1216 1698 2009 3117 4025 7379 8764 CK1221 10540 1145 6289* 6308 CKBOO1 02404 2935* 2947 CKBOOT 02400 2931* 3007 3020 CKMEM 01442 2168* 8157 CKMEM1 01452 2176* 2188 CKSMSG 13402 2200 8284* CLA 7200 834 835 836 837 838 839 840 841 843 845 847 848 849 850 851 852 971 982 1039 1087 1208 1225 1304 1329 1541 1547 1552 1559 1569 1588 1606 1619 1660 1677 1807 1834 1850 1879 1895 1910 1972 2039 2052 2055 2093 2137 2194 2230 2242 2299 2303 2322 2336 2363 2373 2385 2412 2417 2440 2495 2504 2696 2729 2788 2819 2827 2841 2945 2973 3050 3070 3092 3098 3105 3132 3197 3210 3251 3256 3275 3341 3401 3424 3446 3454 3472 3506 3513 3577 3592 3733 3740 3784 3788 3802 3810 3816 3820 3836 3839 3851 3854 3909 3946 4114 4195 4198 4227 4241 4272 4279 4334 4401 4412 4471 4473 4478 4505 4508 4527 4530 4534 4539 4556 4559 4575 4588 4591 4651 4717 4780 4832 4843 4861 4877 4881 4886 4891 4917 4982 5003 5013 5034 5036 5049 5059 5077 5079 5106 5112 5118 5121 5157 5161 5173 5178 5183 5188 5193 5198 5214 5227 5248 5315 5321 5359 5374 5389 5392 5443 5462 5468 5483 5485 5488 5497 5522 5596 5776 5778 5900 5939 5993 6094 6099 6102 6110 6160 6178 6226 6302 6328 6344 6352 6376 6384 6410 6413 6448 6462 6465 6495 6530 6696 6720 6822 6836 6877 6879 6909 6911 6943 6953 6970 7043 7051 7076 7132 7146 7157 7174 7178 7250 7314 7329 7342 7371 7381 7404 7450 7548 7624 7626 7700 7732 7774 7860 7904 7911 7928 7934 8006 8014 8027 8032 8059 8064 8105 8108 8528 8531 8544 8547 8578 8597 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 248 Symbol Table BTS6120.plx 8601 8680 8804 8808 8825 8852 8856 8861 8872 8879 8936 8965 8981 8989 9030 9035 9046 9077 9082 9099 CLL 7100 836 837 838 839 840 841 843 848 2177 2426 2740 2741 2935 3013 3026 3173 3243 4471 4530 4630 4635 4707 4738 4853 4861 4877 5018 5021 5022 5157 5898 5993 6160 6204 6209 6210 6218 6250 6254 6255 6262 6328 6410 6423 6437 6452 6462 6471 6475 6494 6528 6720 6822 6836 6879 6911 7036 7051 7069 7250 7287 7314 7342 7369 7381 7401 7654 7669 7700 7774 7789 7859 7934 8105 8825 8872 8879 9009 9077 CLRCOM 02300 2759* 8189 CLRCPU 02312 2736 2747 2762 2788* 2986 4021 CLRDRD 0006 6644* 6784 6797 7290 7304 7560 CLRDRE 0012 6648* 6707 CLRDWR 0010 6646* 7224 7238 7524 CMA 7040 838 840 841 843 845 989 3181 3208 3273 3943 4238 4302 4879 4884 5466 5568 6374 6720 6879 6911 7051 CMDBUF 00231 1527* 1591 5294 5340 5382 CMDEDD 0220 6676* CMDIDD 0354 6677* 6755 CMDLEN 00140 1498* 5296 5319 5327 5358 5391 5401 5402 CMDRDS 0040 6678* 6886 CMDSDN 0340 6681* 6954 CMDSUP 0341 6680* 6944 CMDTBL 13200 1561 7953 8137* CMDWRS 0060 6679* 6918 CMDX 20600 2260 8804* CMDXP 20603 2263 8808* CMEM 01507 2229* 8161 CMEM0 01512 2219 2231* CMEM1 01534 2243 2249* 2255 CML 7020 836 837 839 3173 3243 4842 4867 4879 4952 6160 6496 6720 6879 6911 7042 7051 7075 7861 COMERR 00453 1481 1588* 4162 8224 8226 8228 8230 8232 8234 8236 8238 8240 8257 8272 8280 CONCHR 07476 5514 5520 5532* CONF1 07027 5141* 5143 CONF2 07052 5153 5156 5161* CONFRM 07025 3049 3908 4113 5140* CONGE1 03330 3511* 3522 3524 CONGE2 03335 3512 3520* CONGET 03325 3399 3407 3430 3442 3477 3506* CONIN 07552 4148 5544 5596* CONLOD 03200 3393* 8191 CONOU1 07465 5518* 5528 CONOU2 07467 5520* 5529 CONOU3 07473 5519 5527* CONOUT 07463 4147 5493 5514* CONT 02216 2636 2657* 2744 2748 2989 4330 CONT1 02227 2627 2665 2690* 5704 CONT2 02225 2674* 5924 CONTCM 02214 2652* 8171 COUNT 00067 1445* 2139 2147 2311 2327 2335 2368 2393 2424 2467 2506 2547 2573 2833 2836 2840 3101 3112 3127 3129 3130 3139 3143 3174 3183 3244 3258 3398 3403 3704 3715 3730 3731 3738 3775 3786 3815 3833 3834 4006 4009 CP1MSG 14056 3914 8329* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 249 Symbol Table BTS6120.plx CP2MSG 4003 3954 8330* CPANEL 01310 2052* 2064 2076 CPBOOT 07600 5618 5619* CPD 6266 1117 1125 2056 2940 4252 4372 4399 5730 5950 7627 7659 7661 7674 7676 7818 7820 8805 8902 9110 CPSAVE 07602 1254 5636* CPYDST 0041 1453* 3891 3906 3960 3978 CPYSRC 0040 1452* 3887 3925 CRLF 07104 1466 4152 5214* 8991 CRLF1 07127 5224 5228 5235* CS1FX 0100 6654* 6656 6657 6658 6659 6660 6661 6662 6663 6664 CS3FX 0200 6655* CTRLO 00051 1425* 5298 5308 5484 5553 5567 5569 CXF 6203 1150 1206 2259 2262 4131 4134 4200 5619 5654 5744 5747 5923 5927 6004 7939 7942 8533 8549 8580 8624 8780 8785 8888 8910 DA1L 20616 8824* 8869 8886 DAC 01200 1937* 8262 DAF 20635 8838 8841* DANDV 01342 1479 2087* DAP 20636 8840 8842* DBCHKS 04153 3973 3988 4003* DCA 3000 984 986 998 1000 1002 1004 1006 1008 1040 1044 1052 1088 1098 1116 1118 1159 1161 1163 1166 1255 1332 1554 1566 1577 1579 1589 1645 1671 1675 1678 1697 1721 1730 1775 1808 1818 1822 1880 1938 1943 1948 1958 1987 2043 2066 2074 2078 2087 2131 2139 2172 2173 2180 2183 2231 2232 2233 2235 2237 2238 2286 2287 2288 2290 2292 2294 2295 2307 2311 2315 2327 2355 2359 2361 2387 2389 2391 2393 2394 2447 2454 2455 2464 2465 2466 2490 2513 2515 2517 2519 2535 2537 2539 2563 2565 2587 2589 2591 2592 2594 2626 2663 2691 2738 2743 2789 2790 2791 2792 2793 2794 2796 2816 2817 2833 2837 2932 2934 2988 3046 3101 3114 3116 3127 3145 3168 3169 3174 3176 3179 3182 3228 3229 3244 3246 3306 3309 3312 3314 3318 3320 3337 3344 3349 3352 3358 3361 3394 3398 3412 3415 3417 3418 3429 3431 3439 3443 3451 3466 3476 3478 3485 3508 3551 3553 3559 3561 3567 3569 3570 3571 3573 3583 3585 3588 3598 3621 3644 3646 3652 3654 3661 3663 3670 3672 3703 3704 3706 3707 3724 3727 3772 3774 3775 3777 3778 3807 3828 3831 3887 3891 3898 3916 3919 3927 3962 3974 3980 4004 4006 4019 4020 4057 4062 4065 4070 4073 4084 4109 4120 4122 4189 4191 4228 4229 4230 4239 4254 4300 4306 4319 4347 4362 4374 4388 4391 4416 4438 4446 4447 4448 4449 4452 4453 4600 4612 4614 4623 4626 4661 4670 4684 4702 4703 4732 4734 4740 4743 4756 4800 4806 4808 4814 4816 4838 4840 4850 4852 4870 4895 4897 4901 4903 4918 4927 4936 4973 4989 5004 5005 5019 5026 5050 5051 5064 5071 5116 5128 5144 5217 5229 5232 5245 5293 5295 5296 5297 5298 5306 5307 5308 5309 5326 5334 5381 5383 5402 5514 5515 5553 5554 5563 5569 5577 5584 5585 5636 5638 5640 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 250 Symbol Table BTS6120.plx 5642 5644 5657 5724 5728 5732 5734 5896 5904 5906 5916 5918 5922 5942 5948 6087 6092 6121 6123 6124 6125 6126 6180 6191 6194 6196 6207 6213 6228 6233 6235 6244 6246 6251 6257 6298 6305 6354 6369 6371 6379 6395 6397 6421 6435 6442 6478 6489 6492 6526 6534 6697 6764 6766 6780 6783 6792 6812 6819 6847 6849 6850 6854 6855 6872 6904 6978 7032 7033 7104 7108 7110 7111 7125 7127 7141 7153 7169 7203 7205 7214 7269 7271 7283 7289 7331 7333 7338 7365 7367 7375 7378 7400 7408 7433 7441 7445 7453 7510 7559 7581 7585 7592 7595 7596 7608 7610 7612 7614 7658 7662 7665 7673 7677 7680 7685 7693 7735 7739 7743 7747 7751 7766 7787 7802 7804 7806 7817 7821 7823 7850 7852 7898 7922 7924 7990 8000 8002 8011 8024 8026 8046 8049 8053 8057 8079 8084 8088 8091 8521 8524 8537 8540 8554 8581 8584 8589 8606 8615 8625 8630 8633 8641 8643 8646 8649 8659 8662 8682 8710 8712 8714 8716 8718 8721 8729 8743 8745 8779 8810 8831 8834 8838 8840 8844 8868 8874 8878 8881 8885 8897 8899 8901 8903 8937 8944 8947 8971 8987 9012 9017 9020 9038 9041 9053 9055 DDBUF 03600 3610 3703* DDBUF2 03605 3710* 3741 DDBUF3 03623 3721* 3734 DDCNT 03652 3703 3739 3747* 3772 3787 DDDUMP 03405 3557* 8193 DDUMP1 03463 3578 3593 3602* 3616 DECNW 06662 1663 1685 1709 1727 5003* DECNW1 06667 5009* 5031 DECNW2 06713 5011 5014 5034* DERCKS 03766 3852 3862* DESTA 20021 8505* 8524 8534 8540 8550 DFLTX 20670 8816 8871* DFRMAT 03072 3303* 8201 DIGITS 00070 1446* 4614 4618 4623 4703 4711 4718 4734 4749 5005 5029 5035 5051 5072 5078 5119 DIOERR 03504 3194 3239 3608 3620* 3680 3933 3968 3986 DISA1 21000 8931 8936* DISA2 20731 8849 8908 8916* DISASM 01546 2259* 8215 DISASMP 01550 2262* 8217 DISKID 11042 1328 6752* DISKIO 12060 7453 7477 7488 7491* DISKRD 11214 3319 3558 3931 3984 6857 6869* 7451 7954 DISKRW 12017 5967 7431* DISKWR 11244 3313 3651 3966 6901* 7451 7452 7955 DKPART 10020 3306 3567 3663 3927 3962 3980 5825* 6854 6979 6986 7331 7336 7340 7365 7376 7445 7957 DKRBN 10021 1495 3939 3944 5826* 6855 6971 6974 7433 7480 7958 7992 8004 8042 DKRW0 12024 7438* DKRW1 12041 7473* 7483 DKRW2 12056 7475 7487* DKSIZE 10022 1333 3068 5827* 6697 6812 6818 6819 6837 6876 6908 7962 DKUNIT 10023 5828* 7367 7368 7373 7400 7403 7406 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 251 Symbol Table BTS6120.plx DLLOAD 03520 3650* 8197 DLOAD 03526 3647 3657* DLOAD1 03540 3667* 3681 4123 DMEM 01067 1879* 8147 DMEM1 01075 1887* 1897 DMQ 01206 1947* 8266 DNAMES 13360 1929 8261* DPC 01203 1942* 8264 DPMEM 01065 1876* 8149 DPNL 20006 8493* 8810 8839 8903 9019 DPS 01211 1952* 8268 DRD1 11225 6878 6882* DREG 01132 1925* 8153 DRVERR 11442 7038 7071 7083* DS1MSG 22266 9061 9344* DS2MSG 22271 9049 9345* DS3MSG 22273 9101 9346* DS4MSG 22275 8923 9347* DS5MSG 22300 8928 9348* DS6MSG 22302 9066 9349* DSKBUF 17400 1332 1340 3175 3245 3705 3773 4003 6763 6808 6813 7607 8048 8083 8478* DSR 01221 1962* 8270 DSTCDF 12265 7673 7691* DSTDAR 0025 7730* 7739 7763 DSTSPD 12266 7677 7692* DWR1 11255 6910 6914* EA2 21073 9006 9010* EA3D 21226 9012 9054 9109* EA3I 21224 9017 9040 9107* EA4 21227 9020 9110* EA6 21144 9047 9051 9058* EA7 21147 9056 9061* EADGRP 21071 9008* 9124 9125 EAIGRP 21067 9005* 9126 EMEM 01002 1807* 8143 EMEM0 01004 1811* 1852 EMEM1 01017 1825* 1837 EMEM2 01021 1826* 1835 EMEM3 01044 1830 1844* ENAMES 13344 1915 8246* EOLNXT 06113 1472 4157 4570* EOLTST 06115 1471 4156 4574* EONE 01042 1813 1840* EPMEM 01000 1804* 8145 ERABLK 12626 8015 8023* EREG 01114 1909* 8151 ERRAST 13670 2498 8307* ERRBTF 13701 2509 8308* ERRCKS 13513 3863 8292* ERRDIO 13502 3623 8291* ERRDSK 14010 3284 3997 8325* 8334 ERRILV 13430 1704 2830 3057 3123 8286* ERRNBP 13653 2376 8305* ERRNBT 13526 3001 8293* ERRNDK 13537 3073 8294* ERRNST 13662 2460 8306* ERROR 00465 1482 1605* 1608 ERRRAN 13453 4846 8288* ERRSRF 13442 2339 8287* ERRWRP 13464 2153 8289* EXMEM 05751 1944 1959 2783 4348 4363 4386 4398* 5799 EXTFLAG 00033 1272 1278 1407* 6350 7902 8682 8779 EXTRO2 20412 8695 8708* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 252 Symbol Table BTS6120.plx EXTROM 20400 1217 8680* F0PATCH 04600 4217* 8769 F0VECTOR 04306 4141* 8768 F1ADDR 04416 4191 4202* F1PATCH 13000 8124* 8771 F1VECTOR 12520 7950* 8770 F1X0 10000 5814* F2PATCH 22400 8773 9355* F2VECTOR 20503 8772 8793* FCFMSG 13743 3044 8321* FCMDCS 0120 4036* 7999 FCMDERA1 0040 4037* 8023 FCMDERA2 0320 4038* 8025 FCMDPROG 0100 4039* 8052 FCMDRA 7777 4034* 4056 4072 4108 8001 8078 FCMDRI 0220 4035* 4064 4083 FIRSTPSS 0020 1398* 8583 8632 8645 8648 FLDTS1 10127 1162* 1165 FLDTS2 10134 1167* 1173 FLDTST 10122 1126 1134 1157* 1177 FLLOAD 04213 4045* 8211 FLMEM 01503 2217* 8163 FLMSG1 14343 4105 8366* FLMSG2 14352 4112 8367* FLNXT 12700 8068 8072* FM1MSG 13763 3166 8322* FM2MSG 13772 3226 8323* 8333 FM3MSG 14003 3325 8324* 8330 FMTARG 02514 3041* 3304 3335 FMTCNT 00073 1451* 3178 3180 3198 3209 3248 3254 3263 3274 3312 3318 3349 3358 FMTP1 02666 3165* 3315 3353 FMTP11 02673 3172* 3211 3213 FMTP12 02701 3178* 3184 FMTP2 03000 3225* 3321 3362 FMTP21 03006 3233* 3276 3278 FMTP22 03023 3248* 3259 FMTP23 03040 3263* 3289 FMTP29 03057 3252 3257 3281* FMTRDP 03012 3237* 3320 3361 FMTWRP 02715 3192* 3314 3352 FNSTAT 00057 1433* 4228 4277 4301 4306 FPDTCT 00056 1432* 4239 4240 4271 4472 4504 7857 FPINIT 05600 1261 4227* FPPGMD 00062 1436* 4544 7852 FPPGMM 00061 1435* 2794 4230 4453 4507 7850 FRDONE 03115 3324* 3365 FTCONT 0310 3504* 3507 FUNTBL 10261 5903 5963* 5989 7952 GCF 6256 5637 GET 00475 1473 1619* 4158 GET1 00515 1623 1639* GET2 00521 1636 1645* GETARG 10241 5893 5895 5939* 6086 7366 7399 7432 7580 7593 7653 7663 7668 7678 7683 7741 7745 7749 7788 7848 7891 GETBAT 10600 5966 6328* GETDKS 11131 5968 6836* GETPMP 12000 5970 7399* GETPP 04000 3885* 3894 3901 GETRDS 11000 5965 6526* GETVER 10303 5963 5993* GOOD 01367 2087 2088 2092 2100 2106* GRP1 21761 9251* GRP2 22161 9302* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 253 Symbol Table BTS6120.plx GRP3 22235 9325* HALTED 07711 2675 5674 5696 5775* HELLO 00701 1265 1738* HELP 00736 1773* 8139 HELP1 00742 1776* 1783 HGHFLD 00042 1416* 2237 2292 4170 4808 4852 4880 8855 8877 8885 HIGH 00040 1414* 1452 1819 1822 2235 2290 4070 4094 4100 4169 4806 4850 4883 8858 8873 8881 HLPB 16366 8392 8449* HLPBL 15421 8385 8424* HLPBM 15116 8382 8414* HLPBP 15346 8385 8422* HLPBPC 15330 8384 8421* HLPBR 15372 8385 8423* HLPC 15547 8388 8430* HLPCK 15153 8382 8415* HLPCM 15301 8382 8418* HLPCTC 17075 8398 8466* HLPCTH 17130 8398 8467* HLPCTL 16730 8397 8462* HLPCTO 17042 8398 8465* HLPCTQ 17004 8398 8464* HLPCTR 17246 8398 8469* HLPCTS 16745 8398 8463* HLPCTU 17301 8398 8470* HLPD 14741 8379 8408* HLPDD 16060 8391 8442* HLPDF 16145 8391 8444* HLPDL 16117 8391 8443* HLPDOL 16703 8395 8459* HLPDP 15005 8379 8409* HLPDR 15052 8379 8410* HLPDSK 15715 8390 8437* HLPE 14511 8378 8403* HLPEDC 14465 8377 8402* HLPEP 14553 8378 8404* HLPER 14616 8378 8405* HLPEX 15642 8388 8433* HLPFL 16343 8392 8448* HLPFM 15247 8382 8417* HLPLP 15727 8391 8438* HLPLST 14365 1774 8375* HLPMEM 15103 8381 8413* HLPMR 15676 8388 8434* HLPMSC 16416 8394 8452* HLPNUL 14464 8381 8384 8387 8390 8394 8397 8399* HLPP 15443 8385 8425* HLPPC 16235 8392 8446* HLPPCC 15471 8387 8428* HLPPE 16274 8392 8447* HLPPM 16172 8392 8445* HLPRD 15754 8391 8439* HLPRF 16035 8391 8441* HLPRL 16011 8391 8440* HLPRP 16641 8395 8458* HLPRUB 17201 8398 8468* HLPSC 16520 8395 8455* HLPSEM 16600 8395 8457* HLPSI 15572 8388 8431* HLPST 15512 8388 8429* HLPTP 16465 8395 8454* HLPTR 15615 8388 8432* HLPTW 16436 8395 8453* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 254 Symbol Table BTS6120.plx HLPVE 16553 8395 8456* HLPWS 15210 8382 8416* HLPX 14643 8378 8406* HLPXP 14702 8378 8407* HLT 7402 2624 HLTMSG 13625 5781 8301* HPOS 00053 1427* 5171 5217 5242 5245 5461 5467 IAC 7001 835 847 848 849 850 851 852 971 1039 1087 2179 3255 3520 4193 4291 4879 6160 6304 6474 6704 7130 8526 8542 8872 8879 IDAMSG 14112 3024 8342* IDBOOT 11200 3019 6846* IDDEV1 11065 6776* 6787 IDDEV2 11103 6793* 6800 IDEINI 11013 1324 6696* IDEINP 0222 6641* 6698 6767 7248 7272 7530 7549 IDEMS1 14275 1322 8357* IDEMS2 14302 1339 8358* IDEMS3 14307 1352 8359* IDEMS4 14320 1347 8360* IDEOUT 0200 6642* 7206 7511 IDERDR 12101 6714 7034 7067 7083 7547* 7551 7552 7563 IDETMP 12122 7510 7520 7559 7562 7566* IDEWRR 12061 6711 6756 6887 6919 6945 6955 6972 6984 6989 6999 7004 7509* 7513 7514 7532 IFDF 20005 8492* 8831 8899 8905 9005 9008 9014 ILLPR0 07707 5756* 5928 INCH10 07356 5322 5406* INCHBS 07300 5358* 5390 INCHR1 07517 5552 5560* INCHR2 07534 5562 5573* INCHR3 07542 5575 5581* INCHR4 07550 5583 5589* INCHRS 07477 2318 4150 5141 5303 5482 5543* INCHW1 07210 1551 3783 5303* 5328 5343 5360 5393 5403 5407 INCHW2 07227 5319* 5375 INCHW3 07242 5313 5331* INCHW4 07264 5333 5346* INCHW5 07275 5348 5355* INCHW6 07312 5357 5367* INCHW7 07326 5369 5372 5380* INCHW8 07335 5316 5388* INCHW9 07350 5364 5399* INCHWL 07200 1549 3782 5293* 5352 INCR 20662 8857 8864* INIPM1 11721 7335* 7341 INIPMP 11713 2782 4024 7329* INLMES 06237 1467 4650* 4652 4654 4655 IOTGRP 21217 9098* 9127 IRMA 00055 1429* 3508 3523 5515 5527 IRNAME 13722 8314* ISZ 2000 1045 1090 1120 1164 1172 2147 2367 2368 2423 2424 2467 2502 2506 2545 2546 2547 2571 2572 2573 2836 3129 3183 3198 3202 3203 3258 3263 3267 3268 3403 3460 3523 3612 3613 3615 3730 3804 3833 3939 4009 4375 4384 4431 4479 4618 4654 4711 4749 4862 4984 5029 5072 5220 5327 5461 5527 5943 6107 6108 6216 6260 6427 6786 6799 7045 7047 7112 7172 7226 7229 7240 7292 7295 7306 7340 7473 7480 7482 7514 7552 7694 7767 7931 7932 8016 8072 8075 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 255 Symbol Table BTS6120.plx 8101 8616 8664 8724 8747 8864 JMP 5000 974 991 1046 1049 1054 1091 1093 1096 1100 1121 1128 1136 1151 1165 1171 1173 1177 1228 1232 1235 1244 1247 1274 1303 1305 1308 1326 1330 1336 1342 1348 1359 1553 1560 1570 1576 1580 1594 1610 1623 1636 1661 1689 1692 1695 1699 1713 1716 1719 1722 1731 1760 1783 1813 1830 1835 1837 1851 1852 1858 1896 1897 1911 1917 1930 1944 1959 1978 1982 1991 2010 2128 2146 2148 2170 2186 2188 2195 2202 2219 2243 2255 2260 2263 2300 2304 2323 2330 2332 2364 2369 2409 2413 2418 2425 2441 2446 2452 2468 2489 2496 2505 2507 2534 2542 2548 2562 2568 2574 2601 2627 2636 2658 2665 2675 2707 2730 2744 2748 2775 2783 2820 2828 2842 2848 2947 2974 2983 2989 2994 2997 3051 3093 3099 3106 3118 3133 3147 3184 3194 3211 3213 3239 3252 3257 3259 3276 3278 3289 3326 3342 3365 3402 3404 3410 3425 3447 3455 3462 3467 3473 3479 3487 3512 3522 3524 3527 3554 3578 3593 3608 3616 3647 3680 3681 3734 3741 3743 3785 3789 3803 3805 3811 3817 3821 3837 3840 3841 3852 3855 3892 3899 3910 3933 3941 3947 3949 3955 3968 3986 4010 4026 4081 4096 4102 4106 4115 4123 4201 4293 4317 4322 4325 4327 4330 4332 4335 4350 4365 4377 4393 4432 4434 4474 4480 4509 4513 4516 4519 4524 4536 4541 4545 4560 4576 4592 4619 4637 4646 4655 4666 4677 4695 4710 4712 4720 4725 4750 4758 4762 4766 4770 4786 4793 4833 4924 4933 4945 4979 4983 4985 4991 5011 5014 5031 5037 5057 5060 5074 5080 5109 5143 5153 5156 5174 5180 5185 5190 5195 5200 5204 5224 5228 5236 5244 5300 5313 5316 5322 5328 5333 5343 5348 5352 5357 5360 5364 5369 5372 5375 5390 5393 5403 5407 5426 5431 5432 5437 5439 5448 5465 5469 5486 5489 5493 5519 5524 5528 5529 5552 5557 5562 5575 5583 5620 5655 5668 5670 5674 5696 5702 5704 5742 5746 5800 5901 5924 5928 6095 6100 6103 6105 6109 6140 6143 6144 6152 6155 6156 6217 6261 6308 6353 6356 6377 6385 6389 6426 6428 6503 6706 6718 6787 6800 6857 6878 6893 6910 6933 6947 6957 7038 7046 7048 7071 7077 7113 7133 7156 7179 7228 7230 7241 7294 7296 7307 7341 7475 7483 7488 7532 7563 7628 7695 7768 7792 7808 7824 7905 7912 7929 7933 8007 8015 8017 8018 8031 8036 8038 8063 8068 8070 8076 8092 8100 8102 8534 8550 8560 8598 8602 8617 8665 8695 8699 8725 8734 8738 8748 8751 8754 8806 8816 8857 8862 8869 8886 8931 8951 8956 8960 8966 8967 8982 8983 9006 9047 9056 9067 9080 9102 JMS 4000 1126 1134 1145 1276 1290 1292 1294 1297 1306 1309 1321 1323 1327 1338 1346 1351 1703 1738 1742 1754 1757 1995 2000 2005 2014 2019 2024 2029 2097 2152 2199 2338 2375 2459 2497 2508 2657 2674 2781 2829 2843 2845 3000 3005 3010 3018 3023 3043 3056 3072 3122 3137 3141 3165 3188 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 256 Symbol Table BTS6120.plx 3191 3225 3233 3236 3283 3324 3339 3602 3605 3622 3674 3677 3862 3895 3904 3913 3923 3930 3953 3958 3965 3976 3983 3996 4023 4104 4111 4845 5682 5712 5748 5752 5756 5780 6187 6201 6231 6241 6711 6714 6756 6887 6919 6945 6955 6972 6984 6989 6999 7004 7034 7067 7083 7122 7210 7276 7734 7738 8558 8722 8765 8812 8818 8821 8918 8921 8926 8990 8996 9059 9064 9089 KCC 6032 783* 1242 KEY 01672 2286 2312 2315 2321 2342* KRB 6036 785* 3514 5599 8696 KRS 6034 784* KSF 6031 782* 1245 3511 5597 8694 L 00013 1393* 1565 1579 1589 1620 1674 4599 4600 5295 5326 5334 5381 5383 5395 LAS 7604 2028 4346 4356 4373 LASTPSS 0033 1403* 8645 8648 LBATMP 11344 6978 6983 7009* LDAR 6410 6065* 6291 6365 6451 7121 7140 7143 7757 7764 7995 8591 8635 8719 LDBU20 03665 3783* 3785 LDBUF 03653 3668 3772* LDBUF2 03662 3781* 3841 LDBUF3 03710 3803 3808* LDBUF4 03727 3825* 3837 LDBUF5 03752 3789 3847* LDPAGE 03770 3777 3801 3804 3807 3858 3866* LENGTH 00031 1401* 1721 4020 5222 LIGHTS 12442 5973 7848* LOW 00041 1415* 1453 1816 2513 2515 2517 2519 4062 4079 4098 4814 4837 4849 4892 4895 LOWFLD 00043 1417* 4816 4839 4851 4898 4901 LSP1 6217 1210 1543 2698 5653 LSP2 6237 2700 MASK 01673 2294 2307 2313 2320 2343* MAT0B 21021 8951 8957* MATCH 06642 1562 1916 1930 2981 4973* MATCH1 06644 4977* 4985 MATCH2 06655 4979 4983 4988* MATCH3 06661 4989 4991 4994* MAXBPT 0010 1519* 1520 1521 1522 1523 2392 MAXCMD 0147 1526* 1527 5320 MAXFUN 0021 5899 5989* MCALL 10201 5746 5893* MCALL1 10225 5915* MCALL2 10237 5901 5927* 5961 MEA 20001 8488* 8606 8616 8649 8664 8987 8988 9038 9053 9058 9111 MEMMOV 12220 5971 7653* MEMMSG 13413 2098 8285* MEMMVX 12276 5972 7732* MEMTS1 10107 1126* 1128 MEMTS2 10114 1134* 1136 MIA 20002 8489* 8721 8724 8745 8747 9041 9052 9055 9063 MM0 6400 898* MM1 6401 899* 1041 MM2 6402 900* 1043 4090 6197 6258 6307 6398 7151 7334 7771 7822 8054 8094 8104 8113 8613 8620 8651 8667 MM3 6403 901* 4045 6188 6242 6292 6366 7123 7805 7997 8051 8056 8097 8593 8608 8637 8654 MNEMP 20000 8487* 8937 8971 9078 9098 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 257 Symbol Table BTS6120.plx MOVE1 01411 2134* 2148 MOVE2 01440 2146 2152* MPTR 20012 8498* 8554 8555 MQA 7501 1957 3438 4361 4636 4896 4902 5639 9036 MQDISP 06075 4519 4539* MQL 7421 1954 2702 3435 4304 4318 4358 4631 4893 4899 6295 7759 7796 9024 MQNAME 13717 2006 8313* MUUO 10047 5844* 5896 5897 5902 5904 5905 5906 5914 5918 5921 6090 6101 7438 7449 7581 7582 7586 7909 MVXARG 12400 7734 7738 7786* 7808 7824 NAME 00045 1419* 1558 4918 4927 4935 4936 4981 NAMENW 06600 1557 1913 1925 2976 4917* NL0000 7200 834* NL0001 7201 835* 6392 6396 7003 NL0002 7326 836* 6164 8753 NL0003 7325 847* 3525 NL0004 7307 848* NL0006 7327 849* NL0010 7215 852* 7335 NL0100 7203 851* NL2000 7332 837* NL3777 7350 838* 1670 5919 NL4000 7330 839* 7589 NL5777 7352 840* NL6000 7333 850* NL7775 7346 841* 842 NL7776 7344 843* 844 NL7777 7240 845* 846 2933 7613 8708 8713 8717 8728 8742 NLM1 7240 846* 3587 6388 6394 NLM2 7344 844* 4624 6303 6355 7611 NLM3 7346 842* 4613 4622 4757 NOBOOT 02462 2983 3000* NODISK 02537 3064* 3303 3557 3650 4164 NOERA 12646 8007 8018 8036 8042* NOMNEM 21222 9080 9101* NOP 7000 1160 1360 1361 1536 1537 1538 2835 3064 3065 3066 3461 4376 4385 4417 5221 5709 5710 5711 5729 5944 5949 6502 6795 6796 6869 6870 6871 6901 6902 6903 7481 7556 7623 7688 7689 7691 7692 7753 7754 7755 7760 7761 7762 8073 NORDM 00311 1303 1308 1311* NOUNIT 02535 3056* 3342 NOXRMES 00263 1274 1281* NOXROM 20477 8699 8734 8738 8780* NUMXRARGS 0007 8759* 8762 NX1 12741 8011 8012 8016 8046 8053 8057 8072 8086 8118* NXTADR 06473 1477 4861* OCTN1 06725 5055* 5074 OCTN2 06750 5057 5060 5077* OCTNF 07004 4798 5112* OCTNF1 07010 5109 5116* OCTNI 07000 2443 2486 2734 5106* OCTNW 06720 1474 4159 5049* OKFLR 04265 4102 4108* OP0 21420 9124 9137* OP1 21424 9124 9139* OP2 21430 9125 9141* OP3 21434 9125 9143* OP4 21440 9126 9145* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 258 Symbol Table BTS6120.plx OP5 21444 9126 9147* OP6 21450 9127 9151* OP6NOCF 21470 9081 9160* OP7 21761 9127 9249* OPJMP 21400 8943 9124* OPRGRP 21200 9077* 9127 OUTCH1 07411 5431 5435* OUTCH2 07416 5437 5442* OUTCH3 07426 5426 5451* OUTCHR 07400 1456 4149 5422* 8559 8919 8997 9090 OUTST1 06204 4617* 4646 OUTST2 06227 4619 4640* OUTST3 06230 4637 4641* OUTSTR 06200 1609 1781 1989 4611* 4653 5791 PAC1 6215 57 PACK 10500 6104 6156 6226* PACK1 10503 6231* 6261 PARMAP 00020 1399* 3113 3144 4172 6852 7332 7374 7407 7440 PARSDX 03413 3554 3564* PCCHK1 04160 4008* 4010 PCNAME 13714 2001 8312* PCOMP 04013 3894* 8213 PCOPY 04022 3901* 8209 PCOPY0 04041 3899 3918* PCOPY1 04044 3923* 3947 3949 PCOPY3 04061 3938* PCOPY4 04076 3941 3952* PCOPYE 04116 3897 3973* PCOPYW 04102 3915 3958* PEX 6004 2706 PGMDSP 06100 4509 4544* PGO 6003 2623 2664 PJ0F2 20100 8520* 8523 8525 8558 8812 8818 8821 8918 8921 8926 8990 8996 9059 9064 9089 PJ1F2 20117 8536* 8539 8541 8722 PM1MSG 14065 3138 8337* PM2MSG 14072 3142 8338* PMALL 02641 3093 3127* 3133 PMEDI1 02637 3099 3122* PMEDIT 02600 3091* 8207 PMSHOW 02652 3106 3128 3137* PNLBUF 12200 3189 3234 3603 3675 3924 3959 3977 7607* PNLCDF 07671 5727 5736* PNLMEM 00037 1413* 1808 1880 2054 2131 2172 2238 2295 2394 2592 3394 PNLTRP 07653 5668 5722* POP1 6235 57 POPJ1 10306 4196 6004* POST 6440 814* 970 980 1085 1114 1215 1224 1253 2693 5658 PPC1 6205 57 PR0 6206 5743 PR0MSG 13560 5757 8298* PR3 6236 815 PRCR 6473 796* PRISLU 6412 790* 8687 PRNMSG 13612 5749 8300* PROCEE 02207 2634* 8177 PROGLP 12655 8051* 8076 PROMPT 00141 1499* 5293 5299 5338 PRPA 6470 793* 6778 7284 PRPB 6471 794* 6781 7281 7557 PRPC 6472 795* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 259 Symbol Table BTS6120.plx PRS 6000 2695 5665 PSDISP 06065 4513 4527* PSNAME 13730 2015 8316* PUSHAC 04417 4189 4199 4203* PUSHAC2 20020 8504* 8521 8532 8537 8548 PUSHJ1 04400 1483 4188* 4190 4192 PWCR 6477 800* 6699 6702 6708 6768 6777 6785 6794 6798 7207 7223 7225 7237 7239 7249 7273 7280 7291 7303 7305 7512 7523 7525 7531 7550 7555 7561 PWPA 6474 797* 7221 PWPB 6475 798* 7216 7521 PWPC 6476 799* 6700 6770 7209 7275 7515 7553 PWRON 07634 5682* R3L 7014 852 971 4755 5114 6475 7795 7814 8879 9009 9027 9044 RAL 7004 843 847 2177 4315 4333 5018 5021 5022 5067 5666 5671 6437 6471 6816 7039 7072 9045 RAM128 1240 6061* 6447 7147 7148 RAM512 5200 6060* 7147 RAMBAS 00034 1408* 4173 6440 8587 8628 RAMBUF 10026 5833* 6191 6194 6196 6202 6206 6208 6212 6233 6235 6243 6245 6247 6251 6252 6256 RAMCDF 10744 6187 6241 6478 6501* 6503 7122 7922 8716 RAMDAR 10031 5834* 6421 6427 6450 RAMDRD 10407 3360 3550 6138* RAMDRW 10310 5964 6085* RAMDWR 10420 3351 3643 6150* RAMER1 10431 6095 6140 6152 6160* 7905 7912 RAMER2 10433 6100 6143 6155 6164* 7929 RAMINIT 04200 1258 4018* RAMMS1 14240 1293 8351* RAMMS3 14245 1298 8352* RAMPTR 10010 5818* 6189 6192 6195 6244 6246 6257 6435 6436 6438 6442 8718 RAMSEL 10713 3340 6093 6138 6150 6462* 7119 RAMSIZ 10043 5837* 7104 7166 7169 7180 RAMUSZ 10045 3348 3357 5839* 6412 6446 6492 6493 7924 RANGE 06441 1475 4160 4829* 8822 RANGE1 06465 4833 4849* RAR 7010 838 839 3173 3243 4511 4514 4517 4742 4790 5917 6809 7036 7069 8828 8907 9086 RDADDR 06416 1883 2129 4798* 4804 4812 RDBFAI 00307 1305 1309* RDBOOT 10400 3006 6120* RDCH10 10614 6353 6364* RDCH11 10644 6385 6392* RDCH12 10651 6356 6377 6389 6397* RDCHK1 10603 1291 6344* RDDUMP 03400 3550* 8195 RDF 6214 1047 1094 1174 8579 8623 RDHIGH 06423 4804* 4836 RDIBU1 11656 7279* 7296 RDIBU2 11700 7302* 7307 RDIBU3 11706 7294 7312* RDIBUF 11646 6893 7269* RDLOW 06432 4812* 4829 RDMEM 01316 1478 2063* 2090 RDPAGE 10025 1494 5832* 6087 6107 6126 6411 6422 7730 7898 7931 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 260 Symbol Table BTS6120.plx RDPMLOC 7700 8573* 8588 8629 RDPMS1 0136 8575* 8596 8640 RDPMS2 0266 8576* 8600 8642 RDPS0 20230 8608* 8617 RDPSS 20201 4026 8578* RDPSX 20240 8581 8598 8602 8619* RDPTR 03467 3551 3559 3606* RDROM 12456 5987 7890* RDRW1 10324 6098* 6109 RDRW2 10336 6103 6106* RDRW3 10340 6105 6107* RDSIZE 10033 5836* 6488 6533 7109 RDTES0 11456 7119* 7179 RDTES1 11510 7133 7151* RDTES2 11525 7156 7172* RDTEST 11446 1295 7104* RDTYPE 10046 5840* 6397 7173 RDUNIT 10024 3337 3569 3661 5831* 6092 6125 6463 6470 6487 6526 6527 6532 7108 7112 7172 7177 7729 RDYTMO 11424 7032 7033 7045 7047 7055* RECCNT 00072 1450* 3573 3588 3598 3615 RECSIZ 00071 1449* 3172 3190 3207 3235 3242 3272 3309 3344 3553 3561 3604 3609 3646 3654 3667 3676 4122 REGCMD 0107 6664* 6757 6888 6920 6946 6956 REGCNT 0102 6658* 7005 REGDAT 0100 6656* 6769 7208 7274 REGERR 0101 6657* 7084 REGLB0 0103 6659* 6973 REGLB1 0104 6660* 6985 REGLB2 0105 6661* 6990 REGLB3 0106 6662* 6712 7000 REGLSC 01240 1911 1981* 2601 5797 REGLST 01224 1972* 1981 REGSTS 0107 6663* 6715 7035 7068 REPCNT 00063 1439* 1554 1574 1577 1671 1678 REPEA1 00615 1661 1670* REPEAT 00600 1659* 8141 REPLOC 00064 1440* 1578 1675 1676 RESTA 00400 1480 1536* 1594 4161 RET0F2 04302 4131* 8529 RET0F3 04304 4134* 4142 RET1F2 12514 7939* 8545 RET1F3 12516 7942* 7951 RET2F3 20501 8785* 8794 RFNS 6434 807* 4274 4298 4475 4510 RFRMAT 03120 3335* 8203 RLLOAD 03513 3643* 8199 RLOF 6435 808* 1540 4256 5775 5788 RLON 6437 809* 2692 ROMCH0 10062 1089* 1091 ROMCH1 10076 1096 1101* ROMCHK 10060 1087* 1100 ROMCK0 00200 1202* 1744 ROMCK1 10200 1747 5859* ROMCK2 20200 1751 8568* ROMCP0 10036 1039* 1054 ROMCP1 10056 1049 1055* ROMCPY 10040 984 986 987 988 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1041* 1046 ROMR1 12501 7927* 7933 ROMWR 12600 4119 7990* RSP1 6207 2690 5641 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 261 Symbol Table BTS6120.plx RSP2 6227 5643 RTF 6005 2704 RTL 7006 836 841 848 849 2741 4323 4328 4630 4738 4739 5066 5672 6204 6209 6210 6814 6815 6980 6981 7287 8044 9028 RTN1 6225 57 RTR 7012 837 840 850 2740 4635 4791 6250 6254 6255 6810 6976 6987 6988 7219 7993 7994 8827 8906 8941 9085 RWCNT 10054 5849* 6108 7473 7482 7592 7612 7932 SAVCHR 00050 1422* 1645 1646 2298 2302 2818 3808 3818 3853 4557 4561 4589 4740 4741 4744 5024 5069 5144 5145 5150 5306 5310 5323 5325 SBBLO 6415 6066* 6393 SCAN 20010 8496* 8729 8731 8735 8765 8944 8946 8986 SCCOM 00670 1727* 8219 SCOPE 00032 1402* 1730 5388 SCPT 6433 806* 5701 SEAR1 01633 2300 2304 2311* SEAR2 01640 2318* 2332 SEAR3 01656 2323 2328* SEAR4 01665 2330 2335* SEARCH 01600 2284* 8159 SETBUF 12123 6085 7431 7580* 7890 SETDA1 10663 6423* 6428 SETDA2 10671 6426 6433* SETDAR 10654 6098 6141 6153 6410* 7927 SETDRD 0007 6643* 6776 6793 7279 7302 7554 SETDRE 0013 6647* 6701 SETDWR 0011 6645* 7222 7236 7522 SETLBA 11310 6885 6917 6970* SETPMP 11732 5969 7365* SHSW 6431 804* 5694 SICOM 02144 2582* 8179 SIMFLG 00047 1421* 2626 2663 5777 SINGLE 02202 2597 2623* 2635 SIZPTR 10044 5838* 6489 6490 6534 6535 7153 7154 SKP 7410 1231 1246 1669 1805 1877 3199 3264 3940 5695 7227 7293 7474 8865 9108 SKPMSG 13475 2844 8290* SMA 7500 1304 1622 1694 1718 2827 4944 4951 5013 5059 5321 5425 6102 7174 7450 SNA 7450 1048 1095 1302 1335 1552 1559 1569 1627 1630 1633 1640 1660 1677 1688 1712 1779 1847 1892 1910 2055 2093 2194 2242 2299 2303 2363 2408 2440 2445 2488 2504 2533 2561 2729 2819 2937 2973 3092 3105 3409 3446 3472 3577 3592 3784 3788 3802 3992 4241 4272 4279 4308 4473 4505 4559 4643 4663 4674 4719 4920 4978 4982 5036 5079 5142 5152 5155 5223 5304 5315 5359 5368 5371 5392 5422 5464 5546 5741 5745 6302 6352 6384 6448 6495 7043 7155 7167 7588 7626 7860 7904 8030 8035 8062 8067 8556 8698 8750 8815 8861 8955 8959 8965 9079 SNCOM 02200 2612* 8173 SNL 7420 1812 2127 2169 2451 2495 2993 2996 3050 3909 4114 4709 4923 4932 6425 7791 7819 9034 9046 SP1NAM 13733 2020 8317* SP2NAM 13737 2025 8318* SPA 7510 1273 1575 1640 1691 1715 4321 4326 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 262 Symbol Table BTS6120.plx 4331 4334 4866 5010 5056 5121 5227 5243 5312 5468 5667 5673 7157 SPACM0 06104 1469 4154 4556* SPACMP 06102 1468 4153 4553* 4560 8813 SPANXT 06122 1926 4584* SPATST 06124 1884 3888 4588* SPD 6276 981 1119 1131 1207 1539 2053 2068 2079 2943 4255 4402 5656 5735 5952 6214 6236 7247 7313 7661 7676 7698 7772 7803 7820 8809 8846 9113 SPINDN 11303 6953* SPINUP 11276 6943* SPLK 6432 805* 4278 4477 SRCCDF 12262 7658 7688* 7695 SRCDAR 0024 7729* 7735 7756 SRCSPD 12263 7662 7689* SRNAME 13725 2030 8315* STA 7240 1115 1241 1573 1667 1804 1876 2138 2234 2289 2293 2326 2625 2795 3776 4236 4437 4598 5231 5241 5384 5400 5576 5722 6120 6846 7168 STACK 0177 1209 1503* 1504 1542 START 02251 2728* 8175 START1 02275 2730 2747* STARTXROM 20462 8751 8761* STKLEN 0034 1504* 1505 STKSAV 00142 1502* 2691 5652 STL 7120 847 849 850 2419 2944 4942 5161 6165 7085 8114 STSBSY 0200 6667* 7040 7073 STSCOR 0004 6672* STSDF 0040 6669* STSDRQ 0010 6671* 7073 7074 STSDSC 0020 6670* STSERR 0001 6673* STSRDY 0100 6668* 7040 7041 SWBOO1 06014 4432 4437* SWBOOT 06007 4317 4431* SWCLR 06017 4327 4446* SWDEP 05725 4335 4371* SWEXA 05735 4332 4384* SWEXA1 05741 4377 4387* SWLA 05702 4322 4346* SWLXA 05711 4325 4356* SWP 7521 7765 7799 7807 SWPADR 06521 2134 2141 4891* SWSCA1 05634 4291* 4293 SWSCAN 05621 1550 4271* SWTEMP 05701 4300 4303 4305 4339* SYSCRN 14164 1758 8348* SYSIN2 00201 1151 1206* SYSIN3 00235 1253* SYSIN4 00346 1326 1330 1351* SYSIN5 00350 1342 1348 1353* SYSIN7 00343 1336 1346* SYSIN9 00352 1359* 4146 SYSINI 10001 970* 5620 SYSNM1 14117 1739 8345* SYSNM2 14136 1743 8346* SYSNM3 14146 1755 8347* SZA 7440 973 990 1092 1127 1135 1170 1243 1694 1718 1834 1850 1895 2322 2336 2373 2412 2417 2841 2945 3070 3098 3132 3210 3251 3256 3275 3401 3424 3454 3521 3733 3740 3810 3816 3820 3836 3839 3851 3854 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 263 Symbol Table BTS6120.plx 3946 4080 4095 4101 4292 4478 4508 4575 4591 4832 4881 5013 5059 5173 5332 5347 5356 5374 5389 5430 5436 5485 5488 5551 5561 5574 5582 5778 6376 6705 6717 6877 6909 7076 7132 7146 7178 7911 8006 8014 8099 8597 8601 8733 8737 8856 8981 9099 SZL 7430 1325 1329 1829 2137 2145 2178 2185 2252 2329 2982 3008 3021 3193 3238 3341 3607 3679 3932 3967 3985 4316 4324 4329 4512 4515 4518 4843 5669 5900 6094 6099 6139 6142 6151 6154 6413 6465 6473 6530 6753 6759 6883 6890 6915 6922 7037 7070 7371 7404 7478 7660 7675 7928 8875 8882 9082 TAD 1000 972 983 985 987 988 997 999 1001 1003 1005 1007 1042 1050 1089 1097 1133 1158 1162 1167 1169 1175 1209 1254 1271 1272 1278 1300 1333 1340 1542 1548 1558 1561 1565 1567 1568 1574 1578 1591 1608 1620 1621 1626 1628 1629 1631 1632 1634 1635 1639 1641 1642 1646 1668 1674 1676 1687 1690 1693 1696 1711 1714 1717 1720 1729 1740 1744 1747 1751 1774 1777 1816 1819 1821 1832 1849 1888 1894 1915 1929 1937 1942 1947 1952 1955 1962 1988 1990 1994 1999 2004 2013 2018 2023 2040 2042 2054 2065 2067 2077 2088 2092 2100 2142 2176 2182 2193 2201 2218 2236 2249 2285 2291 2298 2302 2306 2312 2321 2335 2358 2360 2362 2372 2386 2388 2390 2392 2407 2411 2414 2416 2444 2453 2487 2503 2512 2514 2516 2518 2532 2536 2540 2560 2564 2566 2585 2588 2590 2697 2699 2701 2703 2705 2737 2739 2742 2815 2818 2825 2826 2834 2840 2847 2931 2936 2941 2980 2987 3045 3047 3052 3068 3096 3100 3112 3113 3115 3130 3131 3139 3143 3144 3146 3172 3175 3178 3180 3190 3207 3235 3242 3245 3248 3250 3253 3254 3272 3286 3308 3313 3319 3343 3348 3351 3357 3360 3397 3400 3408 3411 3416 3422 3428 3432 3436 3444 3445 3448 3449 3450 3452 3458 3465 3470 3474 3482 3484 3507 3550 3552 3558 3560 3566 3568 3582 3584 3596 3604 3609 3624 3643 3645 3651 3653 3660 3662 3667 3671 3676 3705 3711 3715 3722 3725 3726 3728 3731 3738 3739 3742 3773 3781 3786 3787 3799 3801 3806 3808 3809 3813 3815 3818 3819 3826 3829 3830 3834 3848 3850 3853 3858 3886 3890 3897 3906 3915 3925 3929 3942 3960 3964 3978 3982 3991 3999 4003 4005 4008 4018 4056 4059 4061 4064 4067 4069 4072 4075 4077 4079 4083 4086 4088 4094 4098 4100 4108 4119 4121 4190 4192 4196 4199 4240 4253 4271 4277 4290 4301 4305 4359 4387 4389 4400 4413 4415 4450 4472 4504 4507 4528 4535 4540 4544 4557 4558 4561 4589 4590 4599 4611 4625 4627 4632 4640 4652 4662 4672 4685 4688 4694 4704 4708 4715 4718 4733 4737 4741 4744 4781 4783 4799 4805 4807 4813 4815 4831 4837 4839 4849 4851 4864 4865 4868 4878 4880 4883 4885 4892 4894 4898 4900 4925 4934 4935 4943 4946 4950 4953 4977 4981 4988 5009 5012 5017 5020 5023 5024 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 264 Symbol Table BTS6120.plx 5025 5035 5055 5058 5063 5065 5069 5070 5078 5107 5113 5119 5120 5125 5145 5150 5151 5154 5171 5179 5184 5189 5194 5199 5203 5215 5222 5226 5235 5242 5246 5294 5299 5310 5311 5314 5319 5320 5323 5325 5331 5335 5338 5340 5346 5349 5355 5358 5367 5370 5373 5378 5382 5388 5391 5395 5401 5424 5429 5435 5438 5444 5447 5451 5463 5467 5484 5487 5520 5550 5555 5560 5564 5567 5573 5581 5589 5652 5723 5725 5727 5731 5733 5739 5740 5743 5777 5790 5792 5795 5897 5899 5902 5903 5905 5912 5921 5941 5945 5947 5951 5994 6090 6101 6122 6179 6189 6192 6195 6202 6206 6208 6212 6227 6232 6234 6243 6245 6247 6252 6256 6290 6294 6300 6329 6350 6364 6368 6370 6372 6373 6381 6383 6411 6412 6422 6424 6433 6436 6438 6440 6446 6447 6449 6450 6463 6464 6470 6472 6477 6487 6488 6490 6493 6527 6529 6532 6533 6535 6698 6701 6703 6707 6710 6716 6755 6763 6765 6767 6769 6776 6784 6791 6793 6797 6808 6813 6818 6837 6848 6852 6856 6876 6886 6892 6908 6918 6924 6944 6954 6971 6974 6979 6983 6986 6998 7031 7041 7074 7107 7109 7120 7124 7126 7128 7129 7139 7142 7144 7147 7148 7154 7158 7159 7166 7173 7175 7176 7177 7180 7204 7206 7208 7213 7215 7217 7222 7224 7236 7238 7248 7270 7272 7274 7279 7288 7290 7302 7304 7330 7332 7336 7368 7370 7373 7374 7376 7402 7403 7406 7407 7410 7438 7440 7443 7449 7451 7452 7476 7487 7511 7513 7520 7522 7524 7530 7549 7551 7554 7560 7562 7582 7584 7586 7594 7607 7609 7625 7655 7657 7659 7661 7664 7670 7672 7674 7676 7679 7690 7733 7737 7742 7746 7756 7758 7763 7790 7801 7803 7805 7812 7816 7818 7820 7822 7851 7857 7897 7902 7909 7921 7923 7992 7999 8001 8004 8012 8013 8023 8025 8028 8033 8037 8042 8048 8052 8055 8060 8065 8069 8078 8083 8086 8087 8090 8095 8098 8109 8111 8523 8525 8529 8532 8539 8541 8545 8548 8555 8580 8583 8587 8588 8595 8596 8599 8600 8604 8610 8612 8624 8628 8629 8632 8640 8642 8645 8648 8653 8697 8711 8715 8720 8731 8732 8735 8736 8744 8746 8762 8805 8809 8826 8830 8833 8836 8837 8839 8843 8853 8855 8858 8860 8866 8867 8873 8876 8877 8880 8883 8884 8896 8898 8900 8902 8905 8917 8920 8923 8925 8928 8939 8943 8946 8949 8953 8958 8963 8970 8972 8986 8995 9005 9008 9011 9014 9016 9019 9022 9026 9031 9043 9049 9052 9058 9061 9063 9066 9078 9081 9084 9088 9098 9101 9111 TADDR 06400 1825 1856 2099 4780* TASCI1 06247 4662* 4666 TASCIZ 06246 1592 4661* 5341 TASZF1 06255 1341 4670* 4677 TASZF2 20136 8554* 8560 8924 8929 9050 9062 9067 9102 TBACKS 07131 1458 5241* TBELL 07071 5188* 5230 5406 TCF 6042 787* 1229 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 265 Symbol Table BTS6120.plx TCKSUM 01472 2193* 3486 TCKSUN 01477 2186 2195 2199* TDECN1 06302 4707* 4712 TDECN2 06310 4710 4715* TDECN3 06320 4720 4724* TDECNW 06277 1464 4163 4702* 4721 TDIGIT 07102 3140 4725 4746 4793 5203* TDOT 07077 1465 5198* TFCHA1 07445 5482* 5489 TFCHA2 07460 5486 5496* TFCHAR 07444 5190 5216 5236 5247 5445 5481* TFIELD 06412 4782 4790* 5794 TFILV 00646 1692 1695 1703* 1716 1719 THCHA1 07443 5465 5469 5471* THCHAR 07427 4695 5180 5185 5195 5200 5204 5439 5448 5460* TLS 6046 789* 1226 1233 5521 TMEM 01060 1840 1856* 2324 2365 4392 TOCT3 06343 1463 4755* TOCT4 06322 1459 4151 4732* 4761 4765 4768 8922 8927 9060 9065 TOCT4C 06352 1460 4765* TOCT4M 06355 1461 4768* TOCT4S 06347 1462 4761* TOCTL 06325 4737* 4750 TOCTN 06324 4734* 4758 TPC 6044 788* TPCOM 00650 1709* 8185 TPCOM1 00666 1713 1721* TQUEST 07066 1590 1593 1607 2196 5140 5183* TRACE 02146 2585* 2658 TRAP 07720 5682 5712 5748 5752 5756 5780 5787* 5790 TRPMSG 13636 5683 8302* TSF 6041 786* 1227 1230 1234 2774 5518 TSIXB 21062 8976 8978 8994* TSIXC 06274 4687 4693* TSIXW 06266 4684* TSLASH 07074 3717 4785 5193* TSPACE 07063 1457 5170 5178* TSTADR 06506 1476 4841 4877* TTABC 07054 5170* 5174 5432 TWCOM 00625 1685* 8183 TWCOM1 00643 1689 1697* TWCOM2 00644 1698* 1722 1731 TYPEAC 01252 1975 1994* 8247 TYPEIR 01263 2009* 2600 4165 TYPEMQ 01260 1976 2004* 8251 TYPEPC 01255 1973 1999* 4349 8249 TYPEPS 01265 1974 2013* 4364 8253 TYPESR 01276 2028* 8255 TYPRG4 01243 1986* 1988 1995 2000 2005 2014 2019 2024 2029 TYPSP1 01270 1977 2018* TYPSP2 01273 1978 2023* UAC 00001 1380* 1938 1994 2705 2789 4144 4449 4535 5636 5912 5916 7851 UFLAGS 00002 1381* 1955 1958 2013 2585 2703 2743 2791 4145 4359 4362 4389 4413 4450 4452 4528 5107 5113 5638 5725 5792 5920 5922 5945 8898 UIR 00007 1386* 2594 4166 5734 5739 8900 UIRPC 00006 1385* 2591 5732 8896 UMQ 00003 1382* 1948 2004 2701 2790 4448 4540 5640 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 266 Symbol Table BTS6120.plx UNPAC1 10441 6187* 6217 UNPACK 10436 6106 6144 6178* 7930 8723 UNPLP 20430 8722* 8725 UPC 00000 1379* 1943 1999 2588 2590 2707 2738 2796 2988 4143 4347 4374 4375 4384 4387 4400 5723 5724 5731 5733 5795 5941 5943 UPDIS1 06067 4529* 4536 4541 4545 UPDIS2 06070 4524 4530* UPDISP 06044 4504* 5524 5543 5703 USERDF 06000 4371 4398 4412* USP1 00004 1383* 2018 2697 2792 4446 5642 USP2 00005 1384* 2023 2699 2793 4447 5644 VALUE 00044 1418* 1987 1990 2066 2067 2074 2077 2142 2231 2249 2355 2367 2372 2837 2847 3046 3047 3052 3439 3458 3465 3482 3621 3624 3724 3725 3728 VECOM 00677 1737* 8181 VERSION 0271 761* 1740 4253 5994 8767 VMAMSG 14105 3011 8341* VPOS 00054 1428* 5220 5226 5229 5309 5585 5657 WDRQ 11426 6758 6889 6921 7067* 7077 WFRDY1 12632 8027* 8031 WFRDY2 12664 8059* 8063 WIDTH 00030 1400* 1697 4019 5463 WORD 00065 1443* 1566 1567 1668 1687 1711 1729 1888 1937 1942 1947 1952 1962 2218 2285 2306 2444 2487 2737 2815 2817 2834 3045 3096 3100 3115 3412 3422 3428 3443 3444 3470 3474 3478 3566 3568 3582 3584 3596 3660 3662 3799 3806 3813 3826 3829 3848 3886 3890 4684 4685 4688 4702 4704 4732 4737 4743 4756 4799 5004 5017 5019 5020 5023 5026 5050 5063 5065 5071 WORDH 00066 1444* 5064 5125 WREAD1 11403 7034* 7046 7048 WREADY 11400 6718 6752 6882 6914 6933 6947 6957 7031* WRIBU1 11610 7213* 7230 WRIBU2 11632 7236* 7241 WRIBU3 11640 7228 7246* WRIBUF 11600 6925 7203* WRMEM 01330 2074* 2089 WRPS0 20266 8651* 8665 WRPSS 20243 1699 3118 7380 8623* WRPSX 20303 8625 8669* WRPTR 03554 3644 3652 3678* 4120 WSR 6246 1963 4529 X1 00010 1390* 2358 2387 2407 2453 2464 2503 2512 2532 2560 2932 2936 3114 3116 3145 3146 3176 3179 3182 3246 3250 3253 3706 3722 3774 3828 4004 4008 4612 4625 4626 4627 4632 4640 4661 4662 4670 4672 4973 4977 4984 4988 X2 00011 1391* 2360 2389 2414 2423 2465 2502 2516 2536 2545 2564 2571 2934 2941 X3 00012 1392* 1775 1777 2391 2466 2539 2546 2566 2572 XCMDDN 20710 8862 8888* XCOMM 20605 8806 8810* XCT1 02340 2820 2825* XCT2 02346 2828 2833* XCT3 02360 2842 2845* XCTBLK 02350 2816 2825 2835* XCTCOM 02324 2814* 8187 XDSCDF 12330 7737 7760* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 267 Symbol Table BTS6120.plx XFRCNT 10051 5846* 6180 6216 6228 6260 6766 6786 6792 6799 7205 7226 7240 7271 7292 7306 7685 7694 7751 7767 XIR 20004 8491* 8844 8901 8925 8939 8949 8953 9022 9026 9043 9084 XOFF 00052 1426* 5232 5297 5307 5487 5554 5563 5577 5584 XPC 20003 8490* 8834 8843 8897 8920 9031 XRCHECK 20453 8746* 8748 XRMES1 14332 1277 8363* XROMERR 20475 8754 8777* XSRCDF 12321 7733 7753* 7768 XTYPIR 20712 2010 8896* XX1 10012 5820* 7110 7111 7333 7338 7375 7378 7408 7410 7441 7443 7665 7690 7743 7758 7787 7802 7804 7806 7817 7821 7823 8049 8055 8084 8095 XX2 10013 5821* 7680 7693 7747 7766 8088 8098 8109 ZBACKS 00076 1458* 5361 5363 ZBACKUP 00112 1470* 1662 1845 1912 2244 2442 2733 2975 3094 3107 3579 3594 4933 5342 5394 5399 ZCOMERR 00125 1481* 1851 1896 2128 2170 2446 2489 3805 3811 3817 3821 3840 3855 4576 4592 4924 5037 5080 ZCRLF 00106 1264 1280 1311 1353 1466* 1544 1756 1759 1760 1782 1836 1844 1917 1982 2325 2366 3012 3025 3282 3326 3737 3955 3995 4350 4365 4393 4433 4766 4769 5147 5337 5351 5380 5470 5566 5789 ZDANDV 00123 1479* 1889 2143 2250 2541 2567 3459 ZDKRBN 00137 1495* 3168 3202 3228 3267 3286 3570 3583 3612 3670 3671 3711 3919 3999 ZEOLNXT 00114 1472* 1737 1914 2353 2582 2612 2634 2652 2759 2977 3393 ZEOLTST 00113 1471* 1664 1686 1710 1728 1773 1928 2130 2171 2246 2308 2491 2735 2822 3042 3109 3599 3658 3892 ZERROR 00126 1482* 1703 2152 2338 2375 2459 2497 2508 2829 3000 3056 3072 3122 3862 4845 ZGET 00115 1473* 2229 2439 2728 3838 4553 4570 4584 4930 5030 5073 ZINLMES 00107 1276 1292 1297 1306 1309 1321 1338 1346 1351 1467* 1738 1742 1754 1757 2097 2199 2843 2845 3010 3023 3043 3137 3141 3165 3225 3283 3324 3622 3895 3904 3913 3953 3996 4104 4111 ZK177 00130 1486* 2942 4641 5545 ZK7 00132 1488* 1821 1833 3732 3835 4745 4792 5172 ZK70 00131 1487* 2041 2236 2291 2586 3475 4390 4414 4869 5108 5115 5127 5726 5793 ZK7400 0135 1493* 4628 4633 ZK7600 0134 1491* ZM128 00134 1490* 1491 3343 3552 3645 ZM256 00135 1492* 1493 3308 3560 3653 3929 3942 3964 3982 4121 ZMSPACE 00133 1489* 4558 4590 4925 4934 5311 5424 ZNXTADR 00121 1477* 1831 1890 2140 2144 2187 2254 2331 ZOCTNW 00116 1474* 1887 1927 2217 2284 2305 2814 2821 3041 3095 3108 3564 3580 3595 3657 3798 3812 3825 3847 3885 3889 5117 ZOUTCHR 00074 1456* 3526 4645 4665 4676 5146 5300 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 268 Symbol Table BTS6120.plx 5324 5336 5339 5350 5379 5396 5556 5565 ZPUSHJ1 00127 1290 1294 1323 1327 1483* 2781 3005 3018 3188 3191 3233 3236 3339 3602 3605 3674 3677 3923 3930 3958 3965 3976 3983 4023 ZRANGE 00117 1475* 1811 2126 2168 2245 2301 ZRDMEM 00122 1478* 1826 1857 2102 2135 2181 2319 2538 2593 ZRDPAGE 00136 1494* 3169 3203 3229 3268 3571 3585 3613 3672 ZRESTA 00124 1359 1480* 1610 3051 3527 3910 4106 4115 4770 5557 5800 ZSPACM0 00111 1469* 1891 2241 3104 3576 3591 4574 4830 ZSPACMP 00110 1468* 1659 1846 1909 2972 3091 4919 5006 5052 ZTDECNW 00104 1279 1296 1337 1464* ZTDOT 00105 1465* 3212 3277 3714 3948 ZTOCT3 00103 1463* 1741 3716 ZTOCT4 00077 1459* 3713 4784 ZTOCT4C 00100 1460* 2202 2848 3147 3288 3743 4001 5796 ZTOCT4M 00101 1461* 2103 3625 ZTOCT4S 00102 1462* 1745 1749 1753 1827 1858 1991 2101 3048 3729 3907 ZTSPACE 00075 1457* 3718 4762 4786 5362 ZTSTADR 00120 1476* 1828 2136 2184 2251 2328 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 269 Table of Contents BTS6120.plx SBC6120 ROM Monitor . . . . . . . . . . . . . . . . . . . . . . 1 BTS6120 Memory Layout . . . . . . . . . . . . . . . . . . . . . 2 Edit History . . . . . . . . . . . . . . . . . . . . . . . . . 4 SBC6120 IOTs and Definitions . . . . . . . . . . . . . . . . . 14 SBC6120 Memory Mapping Hardware . . . . . . . . . . . . . . . . 16 System Startup and POST Codes . . . . . . . . . . . . . . . . . 17 System Startup, Part 1 . . . . . . . . . . . . . . . . . . . . 18 System Startup, Part 2 . . . . . . . . . . . . . . . . . . . . 22 Field 0 Variables . . . . . . . . . . . . . . . . . . . . . . . 26 Monitor Main Loop . . . . . . . . . . . . . . . . . . . . . . . 29 Command Error Processing . . . . . . . . . . . . . . . . . . . 30 Get Next Command Character . . . . . . . . . . . . . . . . . . 31 RP Command -- Repeat . . . . . . . . . . . . . . . . . . . . . 32 TW, TP, SC Commands - Set Terminal Width, Page and Scope . . . 33 VE Command - Show System Name and Version . . . . . . . . . . . 34 H Command - Show Monitor Help . . . . . . . . . . . . . . . . . 35 E and EP Commands -- Examine Main Memory or Panel Memory . . . 36 D and DP Commands -- Deposit in Main Memory or Panel Memory . . 38 ER and DR Commands - Examine and Deposit in Registers . . . . . 39 Deposit in Registers . . . . . . . . . . . . . . . . . . . . . 40 Examine Registers . . . . . . . . . . . . . . . . . . . . . . . 41 Read and Write Memory . . . . . . . . . . . . . . . . . . . . . 43 BM Command -- Memory Block Move . . . . . . . . . . . . . . . . 45 CK Command -- Checksum Memory . . . . . . . . . . . . . . . . . 46 CM and FM Commands -- Clear Memory and Fill Memory . . . . . . 47 X / XP Command Stubs -- Disassemble memory . . . . . . . . . . 48 WS Command -- Word Search Memory . . . . . . . . . . . . . . . 49 BL Command -- List Breakpoints . . . . . . . . . . . . . . . . 51 Search for Breakpoints . . . . . . . . . . . . . . . . . . . . 52 BR Command -- Remove Breakpoints . . . . . . . . . . . . . . . 53 BP Command -- Set Breakpoints . . . . . . . . . . . . . . . . . 54 Insert Breakpoints in Memory . . . . . . . . . . . . . . . . . 55 Remove Breakpoints from Memory . . . . . . . . . . . . . . . . 56 TR Command -- Single Instruction with Trace . . . . . . . . . . 57 SI and P Commands - Single Instruction and Proceed . . . . . . 58 C Command - Restore Main Memory Context and Continue . . . . . 59 ST Command -- Start a Main Memory Program . . . . . . . . . . . 61 MR Command - Master Reset . . . . . . . . . . . . . . . . . . . 62 EX Command - Execute IOT Instructions . . . . . . . . . . . . . 63 OS/8 Bootstrap . . . . . . . . . . . . . . . . . . . . . . . . 64 Boot Sniffer . . . . . . . . . . . . . . . . . . . . . . . . . 66 B Command - Boot Disk . . . . . . . . . . . . . . . . . . . . . 67 Parse FORMAT Unit/Partition Argument . . . . . . . . . . . . . 69 PM Command - Show and Edit Disk Partition Map . . . . . . . . . 70 Disk Formatter, Pass 1 . . . . . . . . . . . . . . . . . . . . 72 Disk Formatter, Pass 2 . . . . . . . . . . . . . . . . . . . . 74 DF Command - Format IDE Disk Partition . . . . . . . . . . . . 76 RF Command - Format a RAM Disk . . . . . . . . . . . . . . . . 77 LP Command - Load Binary Paper Tapes from the Console . . . . . 78 Paper Tape Console Input Routine . . . . . . . . . . . . . . . 81 RD and DD Commands - Dump Disk (RAM and IDE) Records . . . . . 82 RL and DL Commands - Load Disk (RAM and IDE) Records . . . . . 84 Dump Disk Buffer on Console . . . . . . . . . . . . . . . . . . 86 Load Disk Buffer from Console . . . . . . . . . . . . . . . . . 88 PC Command - Copy an IDE Disk Partition . . . . . . . . . . . . 91 Initialize Terminal, Breakpoint, Partition Map, etc . . . . . . 93 FL Command - Flash download . . . . . . . . . . . . . . . . . . 94 Field 0 Vector Table . . . . . . . . . . . . . . . . . . . . . 96 Call Routines in Field 1 . . . . . . . . . . . . . . . . . . . 97 Free Space for Future Expansion! . . . . . . . . . . . . . . . 98 Front Panel Initialization . . . . . . . . . . . . . . . . . . 99 Scan Front Panel Switches . . . . . . . . . . . . . . . . . . . 100 FP LA, LXA, EXAMINE and DEPOSIT Switches . . . . . . . . . . . 102 Change Current DF to User's IF . . . . . . . . . . . . . . . . 104 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 270 Table of Contents BTS6120.plx START, CONTINUE and BOOT Switches . . . . . . . . . . . . . . . 105 HALT Switch . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Update the Front Panel Data Display . . . . . . . . . . . . . . 107 Simple Lexical Functions . . . . . . . . . . . . . . . . . . . 108 Type ASCII Strings . . . . . . . . . . . . . . . . . . . . . . 110 Type SIXBIT Words, and Characters . . . . . . . . . . . . . . . 112 Type Decimal Numbers . . . . . . . . . . . . . . . . . . . . . 113 Type Octal Numbers . . . . . . . . . . . . . . . . . . . . . . 114 Type 15 Bit Addresses . . . . . . . . . . . . . . . . . . . . . 115 Scan Addresses . . . . . . . . . . . . . . . . . . . . . . . . 116 Scan an Address Range . . . . . . . . . . . . . . . . . . . . . 117 Address Arithmetic . . . . . . . . . . . . . . . . . . . . . . 118 Scan a Command Name . . . . . . . . . . . . . . . . . . . . . . 119 Command Lookup and Dispatch . . . . . . . . . . . . . . . . . . 120 Scan Decimal Numbers . . . . . . . . . . . . . . . . . . . . . 121 Scan Octal Numbers . . . . . . . . . . . . . . . . . . . . . . 122 Scan 15 Bit Addresses . . . . . . . . . . . . . . . . . . . . . 123 Ask For Confirmation . . . . . . . . . . . . . . . . . . . . . 124 Type Special Characters . . . . . . . . . . . . . . . . . . . . 125 Type Carriage Return, Line Feed and Backspace . . . . . . . . . 126 Read Command Lines . . . . . . . . . . . . . . . . . . . . . . 128 Terminal Output Primitives . . . . . . . . . . . . . . . . . . 131 Terminal Input Primitives . . . . . . . . . . . . . . . . . . . 133 Control Panel Entry Points . . . . . . . . . . . . . . . . . . 135 Field 1 Variables . . . . . . . . . . . . . . . . . . . . . . . 139 ROM Calls (PR0 Instructions) . . . . . . . . . . . . . . . . . 140 Fetch PR0 Arguments . . . . . . . . . . . . . . . . . . . . . . 142 ROM Call Table . . . . . . . . . . . . . . . . . . . . . . . . 143 Return from Routines in Field 1 . . . . . . . . . . . . . . . . 144 RAM Disk support . . . . . . . . . . . . . . . . . . . . . . . 145 RAM Disk Read/Write ROM Call . . . . . . . . . . . . . . . . . 146 RAM Disk Primary Bootstrap . . . . . . . . . . . . . . . . . . 148 Read and Write RAM Disk Pages . . . . . . . . . . . . . . . . . 149 Unpack RAM Disk Pages . . . . . . . . . . . . . . . . . . . . . 150 Pack RAM Disk Pages . . . . . . . . . . . . . . . . . . . . . . 151 Test DS1221 Batteries . . . . . . . . . . . . . . . . . . . . . 152 Get Battery Status ROM Call . . . . . . . . . . . . . . . . . . 153 Determine RAM Disk Model . . . . . . . . . . . . . . . . . . . 154 Calculate RAM Disk Addresses . . . . . . . . . . . . . . . . . 156 Select RAM Disk Unit . . . . . . . . . . . . . . . . . . . . . 157 Get RAM Disk Size ROM Call . . . . . . . . . . . . . . . . . . 159 ATA Disk Support . . . . . . . . . . . . . . . . . . . . . . . 160 IDE Disk Interface . . . . . . . . . . . . . . . . . . . . . . 162 Initialize IDE Drive and Interface . . . . . . . . . . . . . . 163 Identify IDE/ATA Device . . . . . . . . . . . . . . . . . . . . 164 Get IDE Disk Size ROM Call . . . . . . . . . . . . . . . . . . 166 IDE Disk Primary Bootstrap . . . . . . . . . . . . . . . . . . 167 Read and Write IDE Sectors . . . . . . . . . . . . . . . . . . 168 Spin Up and Spin Down IDE Drive . . . . . . . . . . . . . . . . 170 Setup IDE Unit, LBA and Sector Count Registers . . . . . . . . 171 Wait for IDE Drive Ready . . . . . . . . . . . . . . . . . . . 173 Wait for IDE Data Request . . . . . . . . . . . . . . . . . . . 174 RAM Disk Diagnostics . . . . . . . . . . . . . . . . . . . . . 175 Write IDE Sector Buffer . . . . . . . . . . . . . . . . . . . . 177 Read IDE Sector Buffer . . . . . . . . . . . . . . . . . . . . 179 Initialize Disk Partition Map . . . . . . . . . . . . . . . . . 181 Set Disk Partition Map ROM Call . . . . . . . . . . . . . . . . 182 Get Disk Partition Map ROM Call . . . . . . . . . . . . . . . . 183 IDE Disk Read/Write ROM Call . . . . . . . . . . . . . . . . . 184 Write IDE Register . . . . . . . . . . . . . . . . . . . . . . 186 Read IDE Register . . . . . . . . . . . . . . . . . . . . . . . 187 Setup Disk I/O Buffer . . . . . . . . . . . . . . . . . . . . . 188 Setup Disk I/O Buffer Field and Space . . . . . . . . . . . . . 189 Copy Memory ROM Calls . . . . . . . . . . . . . . . . . . . . . 190 Copy Memory Extended ROM Call . . . . . . . . . . . . . . . . . 192 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 09-JAN-24 22:57:13 Page 271 Table of Contents BTS6120.plx Get Arguments for MEMMOV Calls . . . . . . . . . . . . . . . . 194 LIGHTS Monitor Call . . . . . . . . . . . . . . . . . . . . . . 195 Read Flash ROM Call . . . . . . . . . . . . . . . . . . . . . . 196 Field 1 Vector Table . . . . . . . . . . . . . . . . . . . . . 198 Flash ROM erasure and writing . . . . . . . . . . . . . . . . . 199 Free Space for Future Expansion! . . . . . . . . . . . . . . . 202 Command Names Table . . . . . . . . . . . . . . . . . . . . . . 203 Argument Tables for Various Commands . . . . . . . . . . . . . 205 Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 Help Text . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Temporary Disk Buffer . . . . . . . . . . . . . . . . . . . . . 211 Field 2 Variables . . . . . . . . . . . . . . . . . . . . . . . 212 Field 2 Cross Field Linkages . . . . . . . . . . . . . . . . . 213 Persistent setting support (NVRAM) . . . . . . . . . . . . . . 214 Extension ROM management . . . . . . . . . . . . . . . . . . . 216 Field 2 Vector Table . . . . . . . . . . . . . . . . . . . . . 218 X / XP Commands -- Disassemble memory . . . . . . . . . . . . . 219 Disassemble Current Trace Location . . . . . . . . . . . . . . 221 Disassembler Top Level . . . . . . . . . . . . . . . . . . . . 222 Disassemble EA For MRIs . . . . . . . . . . . . . . . . . . . . 224 Disassemble OPR and IOT instructions . . . . . . . . . . . . . 226 Disassembler Tables (MRIs) . . . . . . . . . . . . . . . . . . 227 Disassembler Tables (IOTs) . . . . . . . . . . . . . . . . . . 228 Disassembler Tables (OPRs) . . . . . . . . . . . . . . . . . . 231 Disassembler Messages . . . . . . . . . . . . . . . . . . . . . 234 Free Space for Future Expansion! . . . . . . . . . . . . . . . 235 Memory Map . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Symbol Table . . . . . . . . . . . . . . . . . . . . . . . . . . 242