PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 1 SBC6120 ROM Monitor BTS6120.PLX 1 .TITLE SBC6120 ROM Monitor 2 3 4 ; Copyright (C) 2001-2003 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 ; * 8KW 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 chage 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 13-JAN-24 18:41:12 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 13-JAN-24 18:41:12 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 ; 263 -- Ensure RDSIZE is always set to zero for non-existent 737 ; SRAM chips (and the odd fields on the IOB6120!). 738 ; 739 ; 264 -- Re-arrange the startup code so that the RAMdisk battery 740 ; test occurs before the EXTROM setup. 741 ; 742 ; 265 -- Fix the RAMdisk detection code so it won't detect extra 743 ; RAMdisk chips on the original RAMdisk card (which didn't 744 ; decode EMA2!). 745 ; 746 ; 266 -- Write RDCHK1, which can correctly test the batteries on 747 ; the new DS1321 RAM disk board and the IOB6120 (which 748 ; doesn't have any low battery detection hardware!). 749 ; 750 ; [End of monitor edit history] 751 0266 VERSION=266 ; latest edit number PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 14 SBC6120 IOTs and Definitions BTS6120.PLX 752 .TITLE SBC6120 IOTs and Definitions 753 754 755 ; The console terminal interface of the SBC6120 is actually straight -8 756 ; compatible, which is a proper subset of the KL8E except that the KCF, TFL, 757 ; KIE and TSK (or SPI, depending on which manual you read!) instructions are 758 ; omitted. Console interrupts are permanently enabled, as they were in the 759 ; original PDP-8. The console interface in the SBC6120 DOES NOT use a 6121, 760 ; so there'll be none of this skip-on-flag-and-clear-it nonsense with KSF or 761 ; TSF! 762 6031 KSF=6031 ; Skip of console receive flag is set 763 6032 KCC=6032 ; Clear receive flag and AC 764 6034 KRS=6034 ; OR AC with receive buffer and DON't clear the flag 765 6036 KRB=6036 ; Read receive buffer into AC and clear the flag 766 6041 TSF=6041 ; Skip if the console transmit flag is set 767 6042 TCF=6042 ; Clear transmit flag, but not the AC 768 6044 TPC=6044 ; Load AC into transmit buffer, but don't clear flag 769 6046 TLS=6046 ; Load AC into transmit buffer and clear the flag 770 6412 PRISLU=6412 ; set console to primary SLU (03/04) 771 772 ; 8255 PPI Interface IOTs... 773 6470 PRPA=6470 ; read PPI port A 774 6471 PRPB=6471 ; " " " B 775 6472 PRPC=6472 ; " " " C 776 6473 PRCR=6473 ; " " control register 777 6474 PWPA=6474 ; write PPI port A 778 6475 PWPB=6475 ; " " " B 779 6476 PWPC=6476 ; " " " C 780 6477 PWCR=6477 ; " " control register 781 782 ; Front panel (FP612) IOTs... 783 6430 CCPR=6430 ; clear AC, HALT SW REQ and 30Hz REQ flags 784 6431 SHSW=6431 ; skip on HALT SW REQ flag 785 6432 SPLK=6432 ; skip on panel lock 786 6433 SCPT=6433 ; skip on 30Hz timer REQ flag 787 6434 RFNS=6434 ; read function switches (BOOT, EXAM, DEP, ROTSW, etc) 788 6435 RLOF=6435 ; turn off RUN LED 789 6437 RLON=6437 ; " on " " 790 ;OSR (7404) read data switches 791 ;WSR (6246) write data LEDs (when ROTSW != MD) 792 793 ; Other SBC6120 instructions... 794 6440 POST=6440 ; Display a 4 bit POST code 795 6236 BPT=PR3 ; Breakpoint trap instruction 796 797 ; Special ASCII control characters that get used here and there... 798 0000 CHNUL=000 ; A null character (for fillers) 799 0003 CHCTC=003 ; Control-C (Abort command) 800 0007 CHBEL=007 ; Control-G (BELL) 801 0010 CHBSP=010 ; Control-H (Backspace) 802 0011 CHTAB=011 ; Control-I (TAB) 803 0012 CHLFD=012 ; Control-J (Line feed) 804 0015 CHCRT=015 ; Control-M (carriage return) 805 0017 CHCTO=017 ; Control-O (Suppress output) 806 0021 CHXON=021 ; Control-Q (XON) 807 0022 CHCTR=022 ; Control-R (Retype command line) 808 0023 CHXOF=023 ; Control-S (XOFF) 809 0025 CHCTU=025 ; Control-U (Delete command line) 810 0033 CHESC=033 ; Control-[ (Escape) 811 0177 CHDEL=177 ; RUBOUT (Delete) 812 813 ; OPR microinstructions that load the AC with various special constants... 814 7200 NL0000=CLA ; all models 815 7201 NL0001=CLA IAC ; all models 816 7326 NL0002=CLA CLL CML RTL ; all models PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 15 SBC6120 IOTs and Definitions BTS6120.PLX 817 7332 NL2000=CLA CLL CML RTR ; all models 818 7350 NL3777=CLA CLL CMA RAR ; all models 819 7330 NL4000=CLA CLL CML RAR ; all models 820 7352 NL5777=CLA CLL CMA RTR ; all models 821 7346 NL7775=CLA CLL CMA RTL ; all models 822 7346 NLM3=NL7775 ; all models 823 7344 NL7776=CLA CLL CMA RAL ; all models 824 7344 NLM2=NL7776 ; all models 825 7240 NL7777=CLA CMA ; all models 826 7240 NLM1=NL7777 ; all models 827 7325 NL0003=CLA STL IAC RAL ; PDP-8/I and later 828 7307 NL0004=CLA CLL IAC RTL ; PDP-8/I and later 829 7327 NL0006=CLA STL IAC RTL ; PDP-8/I and later 830 7333 NL6000=CLA STL IAC RTR ; PDP-8/I and later 831 7203 NL0100=CLA IAC BSW ; PDP-8/E and later 832 7215 NL0010=CLA IAC R3L ; HM6120 only PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 16 SBC6120 Memory Mapping Hardware BTS6120.PLX 833 .TITLE SBC6120 Memory Mapping Hardware 834 835 836 ; The SBC6120 has three memory subsystems - 64K words of twelve bit RAM, 837 ; 8K words of 12 bit EPROM (actually the EPROM is 16 bits wide, but the 838 ; hardware just throws away the extra four bits), and up to 2Mb of 8 bit 839 ; battery backed up SRAM for a RAM disk. 840 ; 841 ; The HM6120 on the other hand, has only two memory spaces - panel memory 842 ; and main memory, and each of these is limited to 32K words. The SBC6120 843 ; implements a simple memory mapping scheme to allow all three memory 844 ; subsystems to fit in the available address space. Up to four different 845 ; memory maps are possible, although only three are currently implemented. 846 ; 847 ; The memory map in use is selected by four IOT instructions, MM0, MM1 848 ; MM2 and (what else) MM3. Memory map changes take place immediately with 849 ; the next instruction fetch - there's no delay until the next indirect JMP 850 ; the way there is with a CIF instruction. 851 ; 852 ; The four memory maps implemented by the SBC6120 are: 853 ; 854 ; * Map 0 uses the EPROM for all direct memory accesses, including instruction 855 ; fetch, and uses the RAM for all indirect memory accesses. This is the 856 ; mapping mode set by the hardware after a power on reset. 857 ; 858 ; * Map 1 uses the RAM for all direct memory accesses, including instruction 859 ; fetch, and uses the EPROM for all indirect memory references. This mode 860 ; is the "complement" of map 0, and it's used by the panel memory bootstrap 861 ; to copy the EPROM contents to RAM. 862 ; 863 ; * Map 2 uses the RAM for all memory accesses, regardless. This is the 864 ; mapping mode used during almost all operation after booting. 865 ; 866 ; * Map 3 is the same as map 2, except that the RAM disk memory is enabled 867 ; for all indirect accesses. BEWARE - RAM disk memory is only eight bits 868 ; wide and reads and writes to this memory space only store and return the 869 ; lower byte of a twelve bit word. This mode is used only while we're 870 ; accessing the RAM disk. 871 ; 872 ; IMPORTANT! The memory mapping mode affects only 6120 control panel memory 873 ; accesses. Main memory is always mapped to RAM regardless of the mapping 874 ; mode selected. 875 876 ; DIRECT INDIRECT 877 ; -------- -------- 878 6400 MM0=6400 ; EPROM RAM (automatically selected by a RESET) 879 6401 MM1=6401 ; RAM EPROM (used during system initialization) 880 6402 MM2=6402 ; RAM RAM (used almost all the time) 881 6403 MM3=6403 ; RAM DISK (used to access RAM disk only) PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 17 System Startup and POST Codes BTS6120.PLX 882 .TITLE System Startup and POST Codes 883 884 885 ; Getting the SBC6120 monitor up and running after a power up is a little 886 ; harder than we might wish. Our first problem is that we're actually 887 ; executing code from the EPROM now, and a lot of the usual PDP-8 techniques 888 ; of "self manipulation" (e.g. a JMS instruction!) won't work because the 889 ; program store isn't writable. Our second problem is that all of panel 890 ; fields 0 and 1 are mapped to EPROM, and there's no RAM anywhere in these 891 ; fields at all, not even in page zero. 892 ; 893 ; Our final problem is that we can't even be sure that all the hardware is 894 ; working correctly at this point. If some part isn't working, for example, 895 ; the RAM, we'd like to provide at least some kind of diagnostic message 896 ; before we end up lost forever. The minimum set of system components that 897 ; this monitor needs to have working before it can print a prompt and execute 898 ; commands is 1) the CPU, 2) the ROM, 3) the RAM, and 4) the console terminal. 899 ; 900 ; This means we need to accomplish two things during a cold boot - first, 901 ; to execute a simple power on self test (aka POST), and second, to copy this 902 ; monitor's code from EPROM to panel RAM where we can execute it without 903 ; restriction. 904 ; 905 ; The SBC6120 has a single digit LED display that the program can set, via 906 ; the POST instruction. At the beginning of each step in testing and 907 ; initialization we set this digit to a particular value, and then if that 908 ; test or startup part fails, we simply halt and the display remains at the 909 ; last value set. The digits and their associated failure modes are: 910 ; 911 ; 7 - CPU failure (or it's not a 6120) 912 ; 6 - panel RAM bootstrap failure 913 ; 5 - RAM checksum failure 914 ; 4 - memory test failure 915 ; 3 - currently unused (reserved for 6121 failure?) 916 ; 2 - console terminal failure 917 ; 1 - panel monitor running (success!) 918 ; 0 - user (main memory) program running PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 18 System Startup, Part 1 BTS6120.PLX 919 .TITLE System Startup, Part 1 920 921 922 ; This code lives in field one, page zero of the EPROM and it's the first 923 ; thing that gets executed after a power on clear. Its main job is to get 924 ; the SBC6120 memory initialized, which it does it with these steps: 925 ; 926 ; 1 - execute a simple CPU test 927 ; 2 - execute a very simple RAM test 928 ; 3 - copy EPROM to panel RAM 929 ; 4 - verify the firmware checksum 930 ; 5 - execute an extensive test on the remaining memory 931 ; 932 ; After it's done, it jumps to the second phase of initialization, which 933 ; lives in field zero. When this code starts we're in memory mapping mode 934 ; zero, which means that all instructions are being executed from EPROM and 935 ; RAM can be addressed only indirectly. When it finishes, all code will be 936 ; in panel RAM and we'll be running in memory mapping mode two, which means 937 ; that all memory accesses go to RAM and the EPROM is inaccesible. 938 ; 939 ; After system initialization is complete, all this code is over written 940 ; with page zero variables and storage for field one. 941 10200 .FIELD 1 942 10000 .PAGE 0 943 944 ; Location zero of field 1 (and field 0, for that matter) must contain a 945 ; zero for the checksum routine. See the code at ROMCHK: for a discussion. 946 10000 0000 0000 947 948 ; The first step is the CPU test, which is trivially simple. We just 949 ; verify that we're actually running on a HM6120 and let it go at that... 950 10001 6447 SYSINI: POST+7 ; set the POST code to 7 951 10002 7215 CLA IAC R3L ; Only a 6120 has the R3L instruction 952 10003 1177 TAD [-10] ; Did we get the right answer? 953 10004 7440 SZA ; ??? 954 10005 5005 JMP . ; Nope - halt forever 955 956 ; Before we copy the boot code to panel RAM, do a primitive (and it's really 957 ; primitive!) test of RAM just to make sure there's something there we can 958 ; read and write. Remember that at this point we're using memory map 0, so 959 ; all direct references are to EPROM, but all indirect references are to RAM. 960 10006 6446 POST+6 ; set the POST code to six 961 10007 6276 SPD ; be sure we're accessing panel memory now! 962 10010 7200 CLA ; ... 963 10011 1176 TAD [2525] ; write an alternating bit pattern 964 10012 3575 DCA @[ROMCPY] ; ... to RAM location zero 965 10013 1174 TAD [5252] ; and write the complement to location 1 966 10014 3573 DCA @[ROMCPY+1] ; ... 967 10015 1575 TAD @[ROMCPY] ; now read them both back 968 10016 1573 TAD @[ROMCPY+1] ; and add them up 969 10017 7040 CMA ; and the result should be -1 970 10020 7440 SZA ; ???? 971 10021 5021 JMP . ; low RAM failure 972 973 ; Copy all of the EPROM moving code, which is six words starting at the label 974 ; ROMCPY, from EPROM to exactly the same location in RAM. There's no way to 975 ; use a loop to do this since we don't have any RAM that we can access directly 976 ; to use as a pointer! 977 10022 1040 TAD ROMCPY ; copy this one word from EPROM 978 10023 3575 DCA @[ROMCPY] ; ... to RAM 979 10024 1041 TAD ROMCPY+1 ; and do it for the entire routine 980 10025 3573 DCA @[ROMCPY+1] ; ... 981 10026 1042 TAD ROMCPY+2 ; ... 982 10027 3572 DCA @[ROMCPY+2] ; ... 983 10030 1043 TAD ROMCPY+3 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 19 System Startup, Part 1 BTS6120.PLX 984 10031 3571 DCA @[ROMCPY+3] ; ... 985 10032 1044 TAD ROMCPY+4 ; ... 986 10033 3570 DCA @[ROMCPY+4] ; ... 987 10034 1045 TAD ROMCPY+5 ; ... 988 10035 3567 DCA @[ROMCPY+5] ; ... 989 990 ; Now it gets tricky. At this instant we're still running in EPROM, and the 991 ; first two instructions (at ROMCP0) get executed from EPROM. As soon as we 992 ; execute the MM1 at ROMCPY:, however, the very next instruction is fetched 993 ; from RAM. This should work, because the previous code has copied the six 994 ; words that make up the ROMCPY loop from EPROM to exactly the same location 995 ; in RAM. 996 ; 997 ; The loop the copies an entire field from EPROM to RAM, executing from RAM 998 ; the whole time. It actually over writes itself in the process, but since it 999 ; over writes itself with a copy of the exact same code we should be OK. By 1000 ; the time it falls thru the ISZ at the end of the loop, the subsequent code 1001 ; should exist in RAM. 1002 ; 1003 ; After copying field 1, we copy fields 2, 3, and 0. There is another 1004 ; subtlety here. The next step will be to checksum the RAM copy, but we're 1005 ; modifying it before we get there! Without some adjustment, the checksum 1006 ; will fail. As it turns out, there is a simple fix- the self-modifying code 1007 ; location is initialized with the value we expect it to have when the copy 1008 ; is complete. This actual instance of the value is never actually executed, 1009 ; but it is seen by the checksum generator and incorporated into the checksum, 1010 ; so everything works out. Although the first time thru we executed ROMCP0 1011 ; from EPROM, the next time thru we execute it from RAM, which is OK because 1012 ; it got copied during the first pass. 1013 ; BTW, Field 3 gets copied to RAM, but BTS6120 is only 3 fields long. Since 1014 ; there won't be a valid checksum in field 3, we will ignore it. 1015 ; 1016 ; Say goodbye to memory map 0 - we'll never need it again! 1017 1018 ; This loop copies all of a field, except location 0, from EPROM to RAM. 1019 10036 7201 ROMCP0: CLA IAC ; always start with location 1, not zero 1020 10037 3566 DCA @[0] ; save the address pointer here 1021 10040 6401 ROMCPY: MM1 ; (1) address RAM directly, EPROM indirectly 1022 10041 1400 TAD @0 ; (2) and load a word from EPROM 1023 10042 6402 MM2 ; (3) address RAM for all memory accesses 1024 10043 3400 DCA @0 ; (4) and store the word in RAM 1025 10044 2000 ISZ 0 ; (5) have we done an entire field? 1026 10045 5040 JMP ROMCPY ; (6) nope - keep copying 1027 10046 6214 RDF ; which field did we just copy? 1028 10047 7450 SNA ; was it 0? 1029 10050 5056 JMP ROMCP1 ; yes, finished copying fields 1030 10051 1165 TAD [CDF 1] ; no, make it a CDF to the next field 1031 10052 0164 AND [7737] ; wrap it around from CDF 3 to CDF 0 1032 10053 3054 DCA .+1 ; and store it to be executed 1033 10054 6201 CDF 0 ; change to new field *** see note above *** 1034 10055 5036 JMP ROMCP0 ; and copy it 1035 10056 ROMCP1: 1036 1037 ; When we leave this loop, we're using memory map 2 which means panel RAM 1038 ; is used everywhere and the EPROM is inaccessible. We'll stay in this mapping 1039 ; mode forever, except when we're accessing the RAM disk. 1040 1041 ; Each field of the panel ROM contains a 12 bit checksum, put there by the 1042 ; PDP2HEX program and calculated so that the sum of all words in the field, 1043 ; including the checksum word, will be zero. Now we'll compute and verify the 1044 ; checksum of both RAM fields, which proves that our RAMs work, that the 1045 ; EPROMS were programmed correctly, and that we copied them correctly. 1046 ; 1047 ; It might seem a better to do this before on the EPROMs before we've copied 1048 ; them to RAM, but the answer is that it's just impossible to compute a PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 20 System Startup, Part 1 BTS6120.PLX 1049 ; checksum using memory map 0 - there's no directly addressible RAM to use for 1050 ; address pointers or for storing the sum! 1051 ; 1052 ; Another issue here is the use of self-modifying code here and in the ROM 1053 ; copy function. Here, like above, we finesse the issue by initializing the 1054 ; modified location to the value it's expected to have (CDF 1) when this field 1055 ; is checksummed. 1056 ; 1057 ; One last subtle point is that we're keeping an address pointer in location 1058 ; zero of RAM, which wasn't in the EPROM when PDP2HEX calculated its checksum. 1059 ; This actually works by accident (er - excuse me, "Design"), since we keep 1060 ; our pointer in location zero of RAM, it will have the value zero when we 1061 ; checksum it. Coincidentally, this is exactly the same value that's in 1062 ; location zero of the ROM image. 1063 1064 ; This loop checksums one RAM field... 1065 10056 6445 POST+5 ; set the POST code to five 1066 10057 6221 CDF 2 ; checksum field 2 first 1067 10060 7201 ROMCHK: CLA IAC ; and start with location 1 (skip zero) 1068 10061 3000 DCA 0 ; ... 1069 10062 1400 ROMCH0: TAD @0 ; add up another word from RAM 1070 10063 2000 ISZ 0 ; have we done an entire field? 1071 10064 5062 JMP ROMCH0 ; nope - keep adding 1072 10065 7440 SZA ; yes - did the checksum pass? 1073 10066 5066 JMP . ; RAM checksum failure 1074 10067 6214 RDF ; get the field we just did 1075 10070 7450 SNA ; was it field 0? 1076 10071 5076 JMP ROMCH1 ; yes, we're done 1077 10072 1163 TAD [6171] ; no, make it previous CDF by adding [CDF 0]-10 1078 10073 3074 DCA .+1 ; and store for execution next 1079 10074 6211 CDF 1 ; *** see note above *** 1080 10075 5060 JMP ROMCHK ; continue checksumming 1081 10076 ROMCH1: 1082 1083 ; The next step is to run a memory test on the remaining fields (2 thru 7) 1084 ; of panel memory and all fields of main memory. It's not a very sophisticated 1085 ; test - it just writes each memory location with its address in the first pass 1086 ; and then reads it back in the second, but it does prove that there's at least 1087 ; some memory out there listening. 1088 ; 1089 ; Before we do that, however, we do an even simpler test to verify that the 1090 ; panel data flag is working and that main memory and panel memory are two 1091 ; separate and distinct memory spaces... 1092 1093 ; Make sure that panel memory and main memory are distinct... 1094 10076 6444 POST+4 ; set the POST code to four 1095 10077 7240 STA ; put -1 in location 0 of panel memory 1096 10100 3566 DCA @[0] ; ... 1097 10101 6266 CPD ; and then put 0 in the same location 1098 10102 3566 DCA @[0] ; ... of main memory 1099 10103 6276 SPD ; back to panel memory 1100 10104 2566 ISZ @[0] ; and increment -1 1101 10105 5105 JMP . ; if it doesn't skip something is wrong 1102 1103 ; Test all eight fields of main memory... 1104 ; CLA ; and start testing with field zero 1105 10106 6266 CPD ; address main memory again 1106 10107 4122 MEMTS1: JMS FLDTST ; test this field, halt if it's bad 1107 10110 7440 SZA ; have we wrapped around to field 0 again ? 1108 10111 5107 JMP MEMTS1 ; no - test the next field 1109 1110 ; Then test only fields 3 thru 7 of panel memory... 1111 10112 6276 SPD ; address panel memory this time 1112 ;*** change this constant to 40 if testing extension ROM code in EPROM 1113 10113 1162 TAD [30] ; start testing with field 2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 21 System Startup, Part 1 BTS6120.PLX 1114 10114 4122 MEMTS2: JMS FLDTST ; test this field, halt if it's bad 1115 10115 7440 SZA ; ... 1116 10116 5114 JMP MEMTS2 ; ... 1117 1118 ; As the last step in this part of the initialization, test the RAMdisk 1119 ; batteries (if a RAMdisk is installed). The DS1221 version of the RAMdisk 1120 ; requires that the battery test be performed before ANY other access to 1121 ; the RAMdisk array, so this has to happen before we can initialize the 1122 ; extension ROM. BTW, note that a) we have no stack yet, and b) the 1123 ; CK1221 routine also lives in field one, and c) CK1221 is only called 1124 ; once, from here! 1125 10117 4561 JMS @[CK1221] ; go test the DS1221 battery 1126 ; CDF 1 ; (CK1221 changes the DF!) 1127 1128 ; System initialization, part 1, is finished. The remainder of the code 1129 ; lives in field zero... 1130 10120 6203 CXF 0 1131 10121 5560 JMP @[SYSIN2] 1132 1133 ; This subroutine will test one field of either main memory or panel memory. 1134 ; It's a fairly simple minded test - it just writes each location with its 1135 ; address in the first pass and then reads it back in the second pass. If the 1136 ; test fails it just halts - there is no error return! 1137 10122 0000 FLDTST: 0 ; enter here with the field in the AC 1138 10123 1157 TAD [CDF 0] ; make a CDF instruction out of it 1139 10124 3125 DCA .+1 ; and execute it inline 1140 10125 7000 NOP ; gets over written with a CDF 1141 10126 3000 DCA 0 ; reset the address pointer 1142 10127 1000 FLDTS1: TAD 0 ; write each word with its address 1143 10130 3400 DCA @0 ; ... 1144 10131 2000 ISZ 0 ; have we done all 4K? 1145 10132 5127 JMP FLDTS1 ; nope - keep going 1146 10133 3000 DCA 0 ; yes - reset the address pointer 1147 10134 1000 FLDTS2: TAD 0 ; and make another pass to test 1148 10135 7041 CIA ; ... what we wrote 1149 10136 1400 TAD @0 ; ... 1150 10137 7440 SZA ; does this location contain the right value? 1151 10140 5140 JMP . ; no - just halt 1152 10141 2000 ISZ 0 ; yes - keep going for all 4K 1153 10142 5134 JMP FLDTS2 ; ... 1154 10143 6214 RDF ; get the data field we just tested 1155 10144 1156 TAD [10] ; and increment it for the caller 1156 10145 0155 AND [70] ; remove any overflow bits 1157 10146 5522 JMP @FLDTST ; return the next field to the caller 1158 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 1159 10200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 22 System Startup, Part 2 BTS6120.PLX 1160 .TITLE System Startup, Part 2 1161 1162 1163 ; This routine is the second phase of system initialization, and it lives 1164 ; in page one of field zero. It's called at the end of the first phase, and 1165 ; it will: 1166 ; 1167 ; 1 - test and initialize any extra hardware (e.g. 6121 chips) 1168 ; 2 - test and initialize the console terminal 1169 ; 3 - initialize any RAM that needs it 1170 ; 4 - print a sign on message 1171 ; 5 - jump to the monitor restart address 1172 ; 1173 ; After this code finishes, the monitor is running and a prompt will have been 1174 ; printed on the terminal. This code code gets overwritten immediately by the 1175 ; monitor's command line buffer, which also lives in page 1 of field 0. 1176 00200 .FIELD 0 1177 00200 .PAGE 1 1178 1179 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 1180 ; HEX format) stores a checksum of ROM field 0 in location 00200, which will 1181 ; later be used by the POST... 1182 00200 ROMCK0: .BLOCK 1 1183 1184 1185 ; Create a software stack and initialize the stack pointer.... 1186 00201 6203 SYSIN2: CXF 0 ; Be sure the IB and DF are both zero 1187 00202 6276 SPD ; Address CP memory with indirect cycles 1188 00203 7200 CLA ; just in case... 1189 00204 1377 TAD [STACK] ; reset the 6120 stack pointer 1190 00205 6217 LSP1 ; ... 1191 1192 ; check for an extension ROM in ramdisk memory at DAR=0000, DF=1, O=0000. 1193 ; The check looks for a signature of 'SB' 'C6' at the start, and a valid 1194 ; checksum. 1195 00206 6443 POST+3 ; set the POST code to three 1196 00207 6222 CIF 2 1197 00210 6205 .PUSHJ @[EXTROM] ; and call the extension ROM check 00211 5776 1198 1199 ; The next stage in initialization is to test the console terminal. Since 1200 ; the SBC6120 hardware doesn't have a loopback mode we can't really verify that 1201 ; data is being sent and received correctly, but we can at least test that the 1202 ; flags set and clear at appropriate times. That way we'll know, at last, that 1203 ; we won't hang forever if we do a "TLS; JMP .-1" loop. 1204 00212 6442 POST+2 ; set the POST code to two 1205 00213 7200 CLA ; send a null character to the console 1206 00214 6046 TLS ; ... 1207 00215 6041 TSF ; and then wait for the flag to set 1208 00216 5215 JMP .-1 ; waiting forever, if necessary! 1209 00217 6042 TCF ; clear the console flag 1210 00220 6041 TSF ; and then test it again 1211 00221 7410 SKP ; good - it _isn't_ set! 1212 00222 5222 JMP . ; bad - it's still set, so the console fails 1213 00223 6046 TLS ; send another null 1214 00224 6041 TSF ; and be sure it sets one more time 1215 00225 5224 JMP .-1 ; ... 1216 1217 ; Now make sure we can clear the keyboard input flag, and that KCC also 1218 ; clears the AC. The latter proves that there is at least some hardware out 1219 ; there controlling the C lines for the console terminal, although it doesn't 1220 ; guarantee that we can receive data. 1221 00226 7240 STA ; Load the AC with -1 1222 00227 6032 KCC ; Clear the keyboard flag and the AC 1223 00230 7440 SZA ; Verify that the AC got cleared PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 23 System Startup, Part 2 BTS6120.PLX 1224 00231 5231 JMP . ; Nope - console test failed! 1225 00232 6031 KSF ; And test the keyboard flag 1226 00233 7410 SKP ; Good - it _isn't_ set! 1227 00234 5234 JMP . ; Bad - the keyboard test failed 1228 1229 ; Set the control panel entry vector in 7777 to be a "JMP CPSAVE" instruction. 1230 ; We have to do this in a rather awkward way because PALX won't assemble a 1231 ; current page reference to CPSAVE unless we're actually on the same page as 1232 ; CPSAVE! 1233 00235 6441 SYSIN3: POST+1 ; the monitor is up and running now 1234 00236 1375 TAD [CPSAVE&177 | 5200] 1235 00237 3774 DCA @[7777] 1236 1237 ; Do any RAM initialization that needs to be done... 1238 00240 6205 .PUSHJ @[RAMINIT] 00241 5773 1239 1240 ; Figure out if we have a front panel (FP612) and, if we do, turn it on... 1241 00242 6205 .PUSHJ @[FPINIT] 00243 5772 1242 1243 ; Type out the system name... 1244 00244 6205 .PUSHJ @ZCRLF ; First start on a new line 00245 5506 1245 00246 6205 .PUSHJ @[HELLO] ; Finally add our name and version 00247 5771 1246 1247 ; Now print information about the extension ROM, if one was found, but 1248 ; it did not initialize properly. Error 2 means that its checksum was 1249 ; invalid. Error 3 or greater means that the ROM initialization was 1250 ; called but it returned this error code. 1251 00250 1370 TAD [-2] ; compare the status code to 2 1252 00251 1033 TAD EXTFLAG 1253 00252 7510 SPA 1254 00253 5263 JMP NOXRMES ; either there is no ROM, or it was OK 1255 1256 00254 4507 JMS @ZINLMES ; say 1257 00255 4332 XRMES1 ; "EXT: Error " 1258 00256 1033 TAD EXTFLAG ; and display the error code 1259 00257 6205 .PUSHJ @ZTDECNW ; ... 00260 5504 1260 00261 6205 .PUSHJ @ZCRLF ; followed by a newline 00262 5506 1261 00263 NOXRMES: 1262 1263 ; Now we are ready to initialize the RAM disk array by first testing the 1264 ; backup battery and then individually testing each of the eight RAM chips to 1265 ; determine a) if one is installed, and b) how big it is. IMPORTANT - because 1266 ; of the way the DS1321 works, we MUST test the backup battery before any 1267 ; other accesses to the RAM disk! The RDTEST routine will automatically 1268 ; initialize the RDSIZE array with the size of each RAM disk chip that it 1269 ; discovers... 1270 00263 4527 JMS @ZPUSHJ1 ; first determine the type of the RAMDisk 1271 00264 0603 RDCHK1 ; .... and set RDTYPE 1272 00265 4507 JMS @ZINLMES ; say 1273 00266 4240 RAMMS1 ; "NVR: " 1274 00267 4527 JMS @ZPUSHJ1 ; (cross field call) 1275 00270 1446 RDTEST ; test all eight RAM disk units 1276 00271 6205 .PUSHJ @ZTDECNW ; type out the total RAM size 00272 5504 1277 00273 4507 JMS @ZINLMES ; say 1278 00274 4245 RAMMS3 ; "KB" 1279 00275 6211 CDF 1 ; the battery OK flag lives in field 1 1280 00276 1767 TAD @[BATTOK] ; get the battery status flag 1281 00277 6201 CDF 0 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 24 System Startup, Part 2 BTS6120.PLX 1282 00300 7450 SNA ; if it's zero the battery status is unknown 1283 00301 5311 JMP NORDM ; ... so say nothing 1284 00302 7700 SMA CLA ; -1 means battery OK 1285 00303 5307 JMP RDBFAI ; and +1 is battery fail 1286 00304 4507 JMS @ZINLMES ; say 1287 00305 4250 BOKMSG ; ... "- Battery OK" 1288 00306 5311 JMP NORDM ; and we're done 1289 00307 4507 RDBFAI: JMS @ZINLMES ; say 1290 00310 4262 BFAMSG ; ... "- Battery FAIL" 1291 00311 6205 NORDM: .PUSHJ @ZCRLF ; finish the status report and we're done 00312 5506 1292 1293 ; Finally, probe the IDE bus for any drive that might be attached. First 1294 ; we have to initialize the 8255 and reset the IDE bus, and then we can send 1295 ; an ATA IDENTIFY DEVICE command to the drive. The DISKID routine will 1296 ; extract the drive's capacity, in MB, from that and leave the result at 1297 ; DKSIZE. DISKID also leaves the first 256 bytes of the drive's response in 1298 ; the DSKBUF, and we can use that to type out the drive's make and model, 1299 ; which appears there in plain ASCII. 1300 00313 4507 JMS @ZINLMES ; say 1301 00314 4275 IDEMS1 ; "IDE: " 1302 00315 4527 JMS @ZPUSHJ1 ; (cross field call) 1303 00316 1013 IDEINI ; initialize the IDE interface 1304 00317 7430 SZL ; is there a drive attached? 1305 00320 5346 JMP SYSIN4 ; nope - quit now 1306 00321 4527 JMS @ZPUSHJ1 ; (cross field call) 1307 00322 1042 DISKID ; send an IDENTIFY DEVICE command to the drive 1308 00323 7630 SZL CLA ; did it work ? 1309 00324 5346 JMP SYSIN4 ; nope - there's no disk there after all 1310 00325 6211 CDF 1 ; disk data lives in field 1 1311 00326 3766 DCA @[DSKBUF+135] ; (make the model string ASCIZ) 1312 00327 1765 TAD @[DKSIZE] ; get the total disk size 1313 00330 6201 CDF 0 ; ... 1314 00331 7450 SNA ; is the disk size zero ? 1315 00332 5343 JMP SYSIN7 ; yes - this disk is "unsupported" ! 1316 00333 6205 .PUSHJ @ZTDECNW ; and type it out in decimal 00334 5504 1317 00335 4507 JMS @ZINLMES ; say 1318 00336 4302 IDEMS2 ; "MB" 1319 00337 1364 TAD [DSKBUF+66-1] ; point to the make/model string 1320 00340 6205 .PUSHJ @[TASZF1] ; and type that out, in ASCII 00341 5763 1321 00342 5350 JMP SYSIN5 ; go type a CRLF and we're done 1322 1323 ; Here if an unsupported (i.e. one which does not support LBA addressing) 1324 ; is detected... 1325 00343 4507 SYSIN7: JMS @ZINLMES ; say 1326 00344 4320 IDEMS4 ; "not supported" 1327 00345 5350 JMP SYSIN5 ; ... 1328 1329 ; Here if no IDE disk is detected... 1330 00346 4507 SYSIN4: JMS @ZINLMES ; and say 1331 00347 4307 IDEMS3 ; "NONE" 1332 00350 6205 SYSIN5: .PUSHJ @ZCRLF ; finish the line and we're done 00351 5506 1333 1334 ; HOOK: End of startup, after BTS6120 messages but before command prompt. 1335 ; Unlike most hooks, this one does not have continuation code after the 1336 ; three hook words; the interceptor must instead jump to RESTA, which 1337 ; is also a hook and therefore known to the extension ROM. 1338 00352 5524 SYSIN9: JMP @ZRESTA ; And we're ready for commands... 1339 00353 7000 NOP ; Hook area for extension ROM 1340 00354 7000 NOP 1341 00363 6255 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 25 System Startup, Part 2 BTS6120.PLX 00364 7465 00365 0022 00366 7535 00367 0032 00370 7776 00371 0701 00372 5600 00373 4200 00374 7777 00375 5202 00376 0400 00377 0177 1342 00400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 26 Field 0 Variables BTS6120.PLX 1343 .TITLE Field 0 Variables 1344 1345 1346 ; Page zero of field zero contains most of the runtime data for the monitor, 1347 ; including the saved state of the user (main memory) program. It is purposely 1348 ; NOT overlayed by any startup code so that it may also contain initialized 1349 ; variables, such as JMP/JMS vectors. Data in this page gets initialized 1350 ; automatically when the first phase of system initialization copies the EPROM 1351 ; to RAM. 1352 1353 ; These words contain the saved state of the main memory (aka user) 1354 ; program. The PC gets saved to location zero automatically by the 6120 1355 ; on any entry to control panel, and the rest get saved by the code around 1356 ; CPSAVE... 1357 00000 .ORG 0000 1358 00000 UPC: .BLOCK 1 ; program counter (saved by the hardware) 1359 00001 UAC: .BLOCK 1 ; accumulator 1360 00002 UFLAGS: .BLOCK 1 ; status (LINK, GT, IF, DF, etc) from GCF 1361 00003 UMQ: .BLOCK 1 ; MQ register 1362 00004 USP1: .BLOCK 1 ; 6120 stack pointer #1 1363 00005 USP2: .BLOCK 1 ; " " " #2 1364 00006 UIRPC: .BLOCK 1 ; program counter where IR was fetched from 1365 00007 UIR: .BLOCK 1 ; the last main memory instruction to be executed 1366 1367 ; Auto-index registers... 1368 00010 .ORG 0010 ; this must be at location 10 !!! 1369 00010 X1: .BLOCK 1 ; the first auto-index register 1370 00011 X2: .BLOCK 1 ; the second auto-index register 1371 00012 X3: .BLOCK 1 ; the third auto-index register 1372 00013 L: .BLOCK 1 ; the command line pointer 1373 1374 00020 .ORG 0020 ; don't put anything else in auto-index locations 1375 1376 ; Persistent settings - will be read from NVRAM if any exists - 1377 0020 FIRSTPSS=. 1378 00020 PARMAP: .BLOCK 10 ; unit number to partition map for eight OS/8 units 1379 00030 WIDTH: .BLOCK 1 ; the width of the terminal 1380 00031 LENGTH: .BLOCK 1 ; the number of lines on the screen 1381 00032 SCOPE: .BLOCK 1 ; 1 if DEL should backspace 1382 0033 LASTPSS=. 1383 ; - end of persistent settings 1384 1385 ; Extension ROM info 1386 00033 EXTFLAG: .BLOCK 1 ; 0=no ext. ROM, 1=OK, 2=Bad checksum, 3..=error code 1387 RAMBAS: .DATA -1 ; RAM disk starting offset - 1 in each field 00034 7777 1388 1389 ; Command parameters... 1390 00035 ADDR: .BLOCK 1 ; the current address 1391 00036 ADRFLD: .BLOCK 1 ; the field of this command 1392 00037 PNLMEM: .BLOCK 1 ; non-zero if ADDR/ADRFLD references panel memory 1393 00040 HIGH: .BLOCK 1 ; the high end of an address range 1394 00041 LOW: .BLOCK 1 ; the low end of an address range 1395 00042 HGHFLD: .BLOCK 1 ; the field of the high address 1396 00043 LOWFLD: .BLOCK 1 ; the field of the low address 1397 00044 VALUE: .BLOCK 1 ; the data word or value 1398 00045 NAME: .BLOCK 1 ; the name of this command 1399 00046 CHKSUM: .BLOCK 1 ; the checksum of memory or tape 1400 00047 SIMFLG: .BLOCK 1 ; non-zero if we're executing a single instruction 1401 00050 SAVCHR: .BLOCK 1 ; a place to save a character 1402 1403 ; Terminal parameters... 1404 00051 CTRLO: .BLOCK 1 ; non-zero if output is supressed 1405 00052 XOFF: .BLOCK 1 ; non-zero if output is suspended 1406 00053 HPOS: .BLOCK 1 ; the current horizontal position PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 27 Field 0 Variables BTS6120.PLX 1407 00054 VPOS: .BLOCK 1 ; the current vertical position 1408 00055 IRMA: .BLOCK 1 ; the console flag timeout counter 1409 1410 ; Front panel data... 1411 00056 FPDTCT: .BLOCK 1 ; non-zero if a FP6120 is present 1412 00057 FNSTAT: .BLOCK 1 ; last known state of the function switches 1413 00060 BTSWCN: .BLOCK 1 ; number of times the BOOT switch was pushed 1414 00061 FPPGMM: .BLOCK 1 ; non-zero for FP "program" mode 1415 00062 FPPGMD: .BLOCK 1 ; program data for program mode 1416 1417 ; Parameters for the repeat command... 1418 00063 REPCNT: .BLOCK 1 ; the number of times to repeat 1419 00064 REPLOC: .BLOCK 1 ; the location to repeat from 1420 1421 ; Number I/O locations... 1422 00065 WORD: .BLOCK 1 ; the number being read or written 1423 00066 WORDH: .BLOCK 1 ; the high order bits of the last word read 1424 00067 COUNT: .BLOCK 1 ; the number of digits read or written 1425 00070 DIGITS: .BLOCK 1 ; counts digits for numeric input/output routines 1426 1427 ; Storage for RDDUMP, DDDUMP, RLLOAD and DLLOAD, RFRMAT, and DFRMAT... 1428 00071 RECSIZ: .BLOCK 1 ; disk (page, block) size 1429 00072 RECCNT: .BLOCK 1 ; number of records to dump 1430 00073 FMTCNT: .BLOCK 1 ; number of blocks/records processed by FORMAT 1431 0040 CPYSRC=HIGH ; source partition for PC command 1432 0041 CPYDST=LOW ; destination partition for PC command 1433 1434 ; Page zero vectors (to save literal space)... 1435 00074 7400 ZOUTCHR: OUTCHR ; type a single character 1436 00075 7063 ZTSPACE: TSPACE ; type a space 1437 00076 7131 ZBACKS: TBACKS ; type a backspace 1438 00077 6322 ZTOCT4: TOCT4 ; type an octal number 1439 00100 6352 ZTOCT4C: TOCT4C ; type an octal number followed by a CRLF 1440 00101 6355 ZTOCT4M: TOCT4M ; type an octal number, a CRLF, and goto RESTA 1441 00102 6347 ZTOCT4S: TOCT4S ; type an octal number followed by a space 1442 00103 6343 ZTOCT3: TOCT3 ; type a 3 digit octal number 1443 00104 6277 ZTDECNW: TDECNW ; type a decimal number 1444 00105 7077 ZTDOT: TDOT ; type a dot (".") 1445 00106 7104 ZCRLF: CRLF ; type a carriage return/line feed 1446 00107 6237 ZINLMES: INLMES ; type a string passed in-line 1447 00110 6101 ZSPACMP: SPACMP ; get the next non-blank command character 1448 00111 6103 ZSPACM0: SPACM0 ; get a non-blank character starting with the current 1449 00112 6131 ZBACKUP: BACKUP ; backup the command line pointer 1450 00113 6114 ZEOLTST: EOLTST ; test current character for end of line 1451 00114 6112 ZEOLNXT: EOLNXT ; test the next character for end of line 1452 00115 0475 ZGET: GET ; get the next character from the command line 1453 00116 6720 ZOCTNW: OCTNW ; scan an octal number 1454 00117 6441 ZRANGE: RANGE ; scan an address range (e.g. "0-7777") 1455 00120 6506 ZTSTADR: TSTADR ; compare the HIGH/HGHFLD to LOW/LOWFLD 1456 00121 6473 ZNXTADR: NXTADR ; increment ADDR/ADRFLD 1457 00122 1316 ZRDMEM: RDMEM ; read a word from main or panel memory 1458 00123 1342 ZDANDV: DANDV ; deposit (in memory) and verify 1459 00124 0400 ZRESTA: RESTA ; monitor restart vector 1460 00125 0453 ZCOMERR: COMERR ; report a command syntax error and restart 1461 00126 0465 ZERROR: ERROR ; print an error message and restart 1462 00127 4400 ZPUSHJ1: PUSHJ1 ; call a routine in field 1 and return to field 0 1463 1464 ; Page zero constants (to save literal space)... 1465 00130 0177 ZK177: 177 ; used everywhere as a mask for ASCII characters 1466 00131 0070 ZK70: 70 ; used as a mask for data/instruction fields 1467 00132 0007 ZK7: 7 ; yet another mask 1468 00133 7740 ZMSPACE: -" " ; an ASCII space character (or the negative there of) 1469 00134 7600 ZM128: -128. ; record size of RAM disk 1470 0134 ZK7600=ZM128 1471 00135 7400 ZM256: -256. ; record size of IDE disk PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 28 Field 0 Variables BTS6120.PLX 1472 0135 ZK7400=ZM256 1473 00136 0025 ZRDPAGE: RDPAGE ; current RAM disk page number in field 1 1474 00137 0021 ZDKRBN: DKRBN ; current IDE disk block number in field 1 1475 1476 ; Local storage for INCHWL... 1477 00140 CMDLEN: .BLOCK 1 ; the length of the current line 1478 00141 PROMPT: .BLOCK 1 ; the prompting character 1479 1480 ; The software stack occupies all of the rest of page zero. 1481 00142 STKSAV: .BLOCK 1 ; the last monitor SP is saved here by CONTINUE 1482 0177 STACK=0177 1483 0034 STKLEN=STACK-. ; Length of the stack (if anybody cares) 1484 00143 .BLOCK STKLEN 1485 1486 1487 ; Page one of field zero contains the second phase system initialization 1488 ; code, and it's over written by the command line buffer and break point 1489 ; tables after we're running. 1490 00200 .ORG 0200 1491 1492 ; The PDP2HEX program stores a checksum of ROM field 0 in location 00200, 1493 ; and we have to reserve space for it here so it doesn't get overwritten by 1494 ; any of our data. See the code at ROMCK0: for more discussion. 1495 00200 .BLOCK 1 1496 1497 ; Breakpoint storage... 1498 0010 MAXBPT=8. ; maximum number of breakpoints 1499 00201 BPTADR: .BLOCK MAXBPT ; address assigned to each breakpoint 1500 00211 BPTFLD: .BLOCK MAXBPT ; field of the breakpoint 1501 00221 BPTDAT: .BLOCK MAXBPT ; original data at the breakpoint 1502 0210 BPTEND=BPTADR+MAXBPT-1 ; end of the breakpoint address table 1503 1504 ; The command line buffer for INCHWL occupies all that remains of page one... 1505 0147 MAXCMD=0400-. ; space available for the command buffer 1506 00231 CMDBUF: .BLOCK MAXCMD ; and the actual command buffer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 29 Monitor Main Loop BTS6120.PLX 1507 .TITLE Monitor Main Loop 1508 1509 00400 .PAGE 2 1510 1511 ; This routine will read commands from the terminal and execute them. It 1512 ; can be entered at RESTA to restart after a control-C or a fatal error, and 1513 ; at BOOTS after completion of a normal command... 1514 ; HOOK: Monitor reentry 1515 00400 7000 RESTA: NOP 1516 00401 7000 NOP 1517 00402 7000 NOP 1518 00403 6276 SPD ; Ensure that CP memory is always selected 1519 00404 6435 RLOF ; The RUN LED is off while we're here 1520 00405 7200 CLA ; And be sure the AC is cleared 1521 00406 1377 TAD [STACK] ; Point to the stack 1522 00407 6217 LSP1 ; Clean up the stack pointer 1523 00410 6205 .PUSHJ @ZCRLF ; Be sure the terminal is ready 00411 5506 1524 1525 ; Read another command line... 1526 00412 7200 BOOTS: CLA ; ... 1527 00413 1376 TAD [">"] ; Point to the prompt 1528 00414 6205 .PUSHJ @[INCHWL] ; Initialize the line input routine 00415 5775 1529 00416 6205 BOOTS0: .PUSHJ @[SWSCAN] ; Scan the switches while we're waiting 00417 5774 1530 00420 6205 .PUSHJ @[INCHW1] ; Read another character into the line 00421 5773 1531 00422 7650 SNA CLA ; EOL? 1532 00423 5216 JMP BOOTS0 ; Nope - keep reading 1533 00424 3063 DCA REPCNT ; Clear the repeat counter initially 1534 1535 ; Execute the next command... 1536 00425 6205 BOOTS1: .PUSHJ @[NAMENW] ; First identify a command 00426 5772 1537 00427 1045 TAD NAME ; Get the name we read 1538 00430 7650 SNA CLA ; Is this a null command ?? 1539 00431 5235 JMP BOOTS2 ; Yes -- just ignore it 1540 00432 1371 TAD [CMDTBL-1] ; Then point to the list of commands 1541 00433 6205 .PUSHJ @[MATCH] ; And look it up 00434 5770 1542 1543 ; See if there are more commands on this line... 1544 00435 1013 BOOTS2: TAD L ; Get the pointer to the last character 1545 00436 3065 DCA WORD ; And save it in a non-autoindex location 1546 00437 1465 TAD @WORD ; Get the last character we saw 1547 00440 1367 TAD [-073] ; Was it a command seperator ?? 1548 00441 7650 SNA CLA ; ???? 1549 00442 5225 JMP BOOTS1 ; Yes -- go execute another command 1550 1551 ; See if this command needs to be repeated... 1552 00443 7240 STA ; Load the AC with -1 1553 00444 1063 TAD REPCNT ; And add to the repeat counter 1554 00445 7510 SPA ; Is the counter positive ?? 1555 00446 5212 JMP BOOTS ; No -- go read anothter line 1556 00447 3063 DCA REPCNT ; Yes -- save the new count 1557 00450 1064 TAD REPLOC ; And get the location to start from 1558 00451 3013 DCA L ; Backup the command scanner 1559 00452 5225 JMP BOOTS1 ; Then go execute this command again PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 30 Command Error Processing BTS6120.PLX 1560 .TITLE Command Error Processing 1561 1562 1563 ; This routine is called when a syntax error is found in the command and it 1564 ; echo the part of the command which has already been scanned inside question 1565 ; marks (very much like TOPS-10 used to do!). After that, the monitor is 1566 ; restarted (i.e. the stack is cleaned up and another prompt issued). 1567 00453 7200 COMERR: CLA ; Ignore the contents of the AC 1568 00454 3413 DCA @L ; And mark the end of what was actually scanned 1569 00455 6205 .PUSHJ @[TQUEST] ; Type the first question mark 00456 5766 1570 00457 1365 TAD [CMDBUF-1] ; And point to the command line 1571 00460 6205 .PUSHJ @[TASCIZ] ; Echo that 00461 5764 1572 00462 6205 .PUSHJ @[TQUEST] ; Then type another question 00463 5766 1573 00464 5200 JMP RESTA ; Go restart the monitor 1574 1575 1576 ; This routine prints an error message and then restarts the monitor. Unlike 1577 ; nearly every other routine in the monitor this one is called via a JMS 1578 ; instruction rather than a .PUSHJ, and that so that the address of the error 1579 ; message can be passed in line, in the word after the JMS. 1580 ; 1581 ; CALL: 1582 ; JMS @ZERROR 1583 ;
1584 00465 0000 ERROR: 0 ; enter here with a JMS 1585 00466 7200 CLA ; the AC is unknown here 1586 00467 6205 .PUSHJ @[TQUEST] ; always type a question mark 00470 5766 1587 00471 1665 TAD @ERROR ; pick up the address of the message 1588 00472 6205 .PUSHJ @[OUTSTR] ; and type that out too 00473 5763 1589 00474 5524 JMP @ZRESTA ; restart the monitor and read another command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 31 Get Next Command Character BTS6120.PLX 1590 .TITLE Get Next Command Character 1591 1592 1593 ; This routine will get the next character from the command line. If the 1594 ; character is lower case, it is folded to upper case. If the character is a 1595 ; TAB, it is converted to a space. And, if the character is ";" or "!" (the 1596 ; start of a comment) it is converted to zero (end of line). Finally, the 1597 ; character is returned in both the AC and location SAVCHR. 1598 00475 7200 GET: CLA ; Be sure the AC is safe to use 1599 00476 1413 TAD @L ; Get another character from the line 1600 00477 1362 TAD [-"A"-40] ; Compare this character to lower case A 1601 00500 7500 SMA ; ??? 1602 00501 5315 JMP GET1 ; It might be a lower case letter 1603 1604 ; The character is not lower case -- check for a TAB, ; or !... 1605 00502 1361 TAD ["A"+40-CHTAB] ; Is this a tab character ?? 1606 00503 7450 SNA ; ??? 1607 00504 1360 TAD [" "-CHTAB] ; Yes -- convert it to a space 1608 00505 1357 TAD [CHTAB-"!"] ; No -- Is it a ! character ?? 1609 00506 7450 SNA ; ??? 1610 00507 1356 TAD [-"!"] ; Yes -- Convert it to a null 1611 00510 1355 TAD ["!"-073] ; Last chance -- is it a ; ?? 1612 00511 7450 SNA ; ??? 1613 00512 1367 TAD [-073] ; Yes -- convert that to zero too 1614 00513 1354 TAD [073] ; No -- restore the original character 1615 00514 5321 JMP GET2 ; Then store the character and return 1616 1617 ; Here if the character might be lower case... 1618 00515 1353 GET1: TAD ["A"-"Z"] ; Compare to the other end of the range 1619 00516 7550 SPA SNA ; ??? 1620 00517 1352 TAD [-40] ; It's lower case -- convert to upper 1621 00520 1351 TAD ["Z"+40] ; Restore the correct character 1622 1623 ; Store the character and return... 1624 00521 3050 GET2: DCA SAVCHR ; Remember this character 1625 00522 1050 TAD SAVCHR ; And also return it in the AC 1626 00523 6225 .POPJ ; And that's it 1627 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 1628 00600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 32 RP Command -- Repeat BTS6120.PLX 1629 .TITLE RP Command -- Repeat 1630 1631 1632 ; This command allows the rest of the command line to be repeated, and it 1633 ; accepts an optional argument which specifes the number of times to repeat, 1634 ; in decimal. The range for this argument is 1 to 2047 and if it is omitted, 1635 ; it defaults to 2047. Note that repeat commands may not be nested; a repeat 1636 ; command will cancel any previous repeat on the same command line. Any error 1637 ; or a control-C will terminate the repetition prematurely. 1638 00600 6205 REPEAT: .PUSHJ @ZSPACMP ; Get the next character 00601 5510 1639 00602 7650 SNA CLA ; Is it the end of the command ?? 1640 00603 5215 JMP REPEA1 ; Yes -- use the default count 1641 00604 6205 .PUSHJ @ZBACKUP ; No -- backup the scanner 00605 5512 1642 00606 6205 .PUSHJ @[DECNW] ; Then read a decimal number 00607 5777 1643 00610 6205 .PUSHJ @ZEOLTST ; Then test for the end of the line 00611 5513 1644 1645 ; Set up the repeat counter... 1646 00612 7240 STA ; Subtract one from the user's 1647 00613 1065 TAD WORD ; argument... 1648 00614 7410 SKP ; ... 1649 00615 7350 REPEA1: NL3777 ; If there's no argument, use 2047 1650 00616 3063 DCA REPCNT ; Set the repeat counter 1651 1652 ; Set up the repeat pointer... 1653 00617 1013 TAD L ; Get the current line pointer 1654 00620 3064 DCA REPLOC ; Remember where to start from 1655 00621 1464 TAD @REPLOC ; Then examine the current character 1656 00622 7650 SNA CLA ; Is the repeat the last command on the line ?? 1657 00623 3063 DCA REPCNT ; Yes -- this is all pointless after all 1658 00624 6225 .POPJ ; Then proceed with the next command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 33 TW, TP, SC Commands - Set Terminal Width, Page and Scope BTS6120.PLX 1659 .TITLE TW, TP, SC Commands - Set Terminal Width, Page and Scope 1660 1661 1662 ; The TW command sets the terminal screen width to the value of its argument, 1663 ; which is a _decimal_ number. Screen widths are limited to the range 32..255. 1664 00625 6205 TWCOM: .PUSHJ @[DECNW] ; read a decimal operand again 00626 5777 1665 00627 6205 .PUSHJ @ZEOLTST ; then check for the end of the line 00630 5513 1666 00631 1065 TAD WORD ; get the desired width 1667 00632 7450 SNA ; is it zero ?? 1668 00633 5243 JMP TWCOM1 ; yes -- that disables automatic returns 1669 00634 1376 TAD [-32.] ; compare it to 32 1670 00635 7510 SPA ; is it at least 32 ?? 1671 00636 5246 JMP TFILV ; no -- ?ILLEGAL VALUE 1672 00637 1375 TAD [32.-255.] ; now compare it to 255 1673 00640 7540 SMA SZA ; it can't be bigger than that 1674 00641 5246 JMP TFILV ; but it is... 1675 00642 1374 TAD [255.] ; restore the original number 1676 00643 3030 TWCOM1: DCA WIDTH ; and set the terminal width 1677 00644 6222 TWCOM2: CIF 2 1678 00645 5773 JMP @[WRPSS] ; store it in NVRAM if it exists 1679 ; and we're all done 1680 1681 ; Here if the parameter value is illegal... 1682 00646 4526 TFILV: JMS @ZERROR ; yes -- it isn't legal 1683 00647 3430 ERRILV ; ?ILLEGAL VALUE 1684 1685 ; The TP command sets the terminal page size to the value of its argument, 1686 ; in _decimal_. Page sizes may range from 12 to 48, or zero. A value of zero 1687 ; disables the automatic XOFF function completely. 1688 00650 6205 TPCOM: .PUSHJ @[DECNW] ; Read a decimal operand 00651 5777 1689 00652 6205 .PUSHJ @ZEOLTST ; And check for the end of the line 00653 5513 1690 00654 1065 TAD WORD ; Get the value he gave 1691 00655 7450 SNA ; Is it zero ?? 1692 00656 5266 JMP TPCOM1 ; Yes -- that is legal (to disable) 1693 00657 1372 TAD [-12.] ; Compare it to 12 lines 1694 00660 7510 SPA ; We have to have at least that many 1695 00661 5246 JMP TFILV ; No -- ?ILLEGAL VALUE 1696 00662 1376 TAD [16.-48.] ; Then compare it to 48 1697 00663 7540 SMA SZA ; Is it more than that ?? 1698 00664 5246 JMP TFILV ; Yes -- that won't work, either 1699 00665 1371 TAD [48.] ; Restore the original number 1700 00666 3031 TPCOM1: DCA LENGTH ; And set the new terminal length 1701 00667 5244 JMP TWCOM2 1702 1703 ; The SC command sets the SCOPE flag to its operand. When non-zero, the 1704 ; line input command will respond to a DEL with a destructive backspace 1705 ; instead of the default echo. 1706 00670 6205 SCCOM: .PUSHJ @[DECNW] ; Read a decimal operand 00671 5777 1707 00672 6205 .PUSHJ @ZEOLTST ; And check for the end of the line 00673 5513 1708 00674 1065 TAD WORD ; Get the value he gave 1709 00675 3032 DCA SCOPE 1710 00676 5244 JMP TWCOM2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 34 VE Command - Show System Name and Version BTS6120.PLX 1711 .TITLE VE Command - Show System Name and Version 1712 1713 1714 ; This routine will type the name and version of the monitor. It is called 1715 ; at startup, and by the VE command. 1716 00677 6205 VECOM: .PUSHJ @ZEOLNXT ; enter here for the VE command 00700 5514 1717 00701 4507 HELLO: JMS @ZINLMES ; type out the name of the system 1718 00702 4117 SYSNM1 ; ... 1719 00703 1370 TAD [VERSION] ; get the present edit level 1720 00704 6205 .PUSHJ @ZTOCT3 ; type that in octal 00705 5503 1721 00706 4507 JMS @ZINLMES ; say 1722 00707 4136 SYSNM2 ; "Checksum " 1723 00710 1767 TAD @[ROMCK0] ; get the checksum of ROM field 0 1724 00711 6205 .PUSHJ @ZTOCT4S ; type that and a space 00712 5502 1725 00713 6211 CDF 1 ; then do the same for ROM field 1 1726 00714 1767 TAD @[ROMCK1] ; ... 1727 00715 6201 CDF 0 ; ... 1728 00716 6205 .PUSHJ @ZTOCT4S ; this time end with a CRLF 00717 5502 1729 00720 6221 CDF 2 ; and do the same for ROM field 2 1730 00721 1767 TAD @[ROMCK2] ; ... 1731 00722 6201 CDF 0 ; ... 1732 00723 6205 .PUSHJ @ZTOCT4S ; this time end with a CRLF 00724 5502 1733 00725 4507 JMS @ZINLMES ; finally, type the system date 1734 00726 4146 SYSNM3 ; ... 1735 00727 6205 .PUSHJ @ZCRLF ; finish that line 00730 5506 1736 00731 4507 JMS @ZINLMES ; then type the copyright notice 1737 00732 4164 SYSCRN ; ... 1738 00733 6205 .PUSHJ @ZCRLF 00734 5506 1739 00735 5506 JMP @ZCRLF ; finish that line and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 35 H Command - Show Monitor Help BTS6120.PLX 1740 .TITLE H Command - Show Monitor Help 1741 1742 ; The H command generates a simple list of all monitor commands and a 1743 ; brief, one line, help message for each. The whole function is driven 1744 ; by a table of help messages stored in field one - this table contains 1745 ; a list of pointers and each pointer points to the packed ASCII text of 1746 ; a single line of help. We simply print each line and add a CRLF at the 1747 ; end. It's done this way (as a table of lines) rather than as a single, 1748 ; huge, string with embedded CRLFs because the automatic XOFF (i.e. terminal 1749 ; page) processing is done via the CRLF routine. Embedded CRLFs wouldn't 1750 ; automatically XOFF, and so most of the text would scroll right off the 1751 ; top of the CRT. 1752 00736 6205 HELP: .PUSHJ @ZEOLTST ; no arguments are allowed 00737 5513 1753 00740 1366 TAD [HLPLST-1] ; point to the list of help messages 1754 00741 3012 DCA X3 ; in an auto index register 1755 00742 6211 HELP1: CDF 1 ; the help text and table lives in field 1 1756 00743 1412 TAD @X3 ; get the next help message 1757 00744 6201 CDF 0 ; back to our field 1758 00745 7450 SNA ; end of list? 1759 00746 6225 .POPJ ; yes - we can quit now 1760 00747 6205 .PUSHJ @[OUTSTR] ; nope - type this string 00750 5765 1761 00751 6205 .PUSHJ @ZCRLF ; and finish the line 00752 5506 1762 00753 5342 JMP HELP1 ; keep typing until we run out of strings 1763 00765 6200 00766 4364 00767 0200 00770 0266 00771 0060 00772 7764 00773 0243 00774 0377 00775 7441 00776 7740 00777 6662 1764 01000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 36 E and EP Commands -- Examine Main Memory or Panel Memory BTS6120.PLX 1765 .TITLE E and EP Commands -- Examine Main Memory or Panel Memory 1766 1767 1768 ; The E command allows the user to examine the contents of memory in octal, 1769 ; either one word at a time or an entire range of addresses. In the latter 1770 ; case a memory dump is printed with eight PDP-8 words per line. It accepts 1771 ; several forms of operands, for example: 1772 ; 1773 ; >E 1234 -> Examine location 1234 in the data field 1774 ; >E 01234 -> Examime location 1234 of field zero 1775 ; >E 41234 -> Examine location 1234, field 4 1776 ; >E 71000-2000 -> Examine locations 1000 through 2000, field 7 1777 ; >E 50000-77777 -> Examine location 0, field 5 thru 7777, field 7 1778 ; 1779 ; The EP command is identical to E, except that panel memory is examined 1780 ; rather than main memory. 1781 1782 ; Enter here for the EP command... 1783 01000 7240 EPMEM: STA ; set the PNLMEM flag 1784 01001 7410 SKP ; fall into the regular code 1785 ; Enter here for the E command... 1786 01002 7200 EMEM: CLA ; clear the PNLMEM flag 1787 01003 3037 DCA PNLMEM ; to reference main memory 1788 1789 ; Both forms join up here... 1790 01004 6205 EMEM0: .PUSHJ @ZRANGE ; go read an address range 01005 5517 1791 01006 7420 SNL ; was there just one address ??? 1792 01007 5242 JMP EONE ; yes -- just examine one location 1793 1794 ; Fix up the address range for multiple word examines... 1795 01010 1041 TAD LOW ; get the low boundry 1796 01011 0377 AND [7770] ; round it down to a multiple of 8 1797 01012 3035 DCA ADDR ; then it becomes the starting address 1798 01013 1040 TAD HIGH ; get the ending address 1799 01014 0377 AND [7770] ; round it up to a multiple of 8 1800 01015 1132 TAD ZK7 ; ... 1801 01016 3040 DCA HIGH ; and remember the last address to process 1802 1803 ; Type out lines of 8 memory locations... 1804 01017 6205 EMEM1: .PUSHJ @[TADDR] ; type out the address of the next word 01020 5776 1805 01021 6205 EMEM2: .PUSHJ @ZRDMEM ; go read a word from main memory 01022 5522 1806 01023 6205 .PUSHJ @ZTOCT4S ; type the word in octal 01024 5502 1807 01025 6205 .PUSHJ @ZTSTADR ; have we done all the locations ?? 01026 5520 1808 01027 7430 SZL ; are we there yet ??? 1809 01030 5244 JMP EMEM3 ; yes -- finish the line and return 1810 01031 6205 .PUSHJ @ZNXTADR ; no -- increment to the next address 01032 5521 1811 01033 1035 TAD ADDR ; get the current address 1812 01034 0132 AND ZK7 ; is it a multiple of 8 ?? 1813 01035 7640 SZA CLA ; ??? 1814 01036 5221 JMP EMEM2 ; no -- keep typing 1815 01037 6205 .PUSHJ @ZCRLF ; yes -- start on a new line 01040 5506 1816 01041 5217 JMP EMEM1 ; and type the next address 1817 1818 ; Here to examine a single memory location... 1819 01042 6205 EONE: .PUSHJ @[TMEM] ; type out the contents of memory 01043 5775 1820 ; and fall into the next range 1821 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 37 E and EP Commands -- Examine Main Memory or Panel Memory BTS6120.PLX 1822 ; Here when we've finished examining one range of addresses... 1823 01044 6205 EMEM3: .PUSHJ @ZCRLF ; finish the current line 01045 5506 1824 01046 6205 .PUSHJ @ZBACKUP ; backup the command line pointer 01047 5512 1825 01050 6205 .PUSHJ @ZSPACMP ; ... and get the next character 01051 5510 1826 01052 7450 SNA ; is it the end of the line ?? 1827 01053 6225 .POPJ ; yes -- just stop now 1828 01054 1374 TAD [-","] ; no -- check for a comma 1829 01055 7640 SZA CLA ; ???? 1830 01056 5525 JMP @ZCOMERR ; this isn't legal 1831 01057 5204 JMP EMEM0 ; yes -- do another operand 1832 1833 ; This routine will type the address and contents of the memory location 1834 ; indicated by registers ADDR and ADRFLD. 1835 01060 6205 TMEM: .PUSHJ @[TADDR] ; first type the address 01061 5776 1836 01062 6205 .PUSHJ @ZRDMEM ; then load the indicated word 01063 5522 1837 01064 5502 JMP @ZTOCT4S ; type it out and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 38 D and DP Commands -- Deposit in Main Memory or Panel Memory BTS6120.PLX 1838 .TITLE D and DP Commands -- Deposit in Main Memory or Panel Memory 1839 1840 1841 ; The D command allows the user to deposit one or more words in memory. The 1842 ; general format is: 1843 ; 1844 ; >D 60123 4567 -> Deposit 4567 into location 0123, field 6 1845 ; >D 40000 1,2,3,4 -> Deposit 0001 into location 0, field 4, and 0002 1846 ; into location 1, field 4, and 0003 into location 1847 ; 2, etc... 1848 ; 1849 ; The DP command is identical to D, except that panel memory is chaged rather 1850 ; than main memory. WARNING - there is no protection against changing the 1851 ; monitor when using this command, so it's up to the user to make sure the 1852 ; changes don't corrupt something important! 1853 1854 ; Enter here for the DP command... 1855 01065 7240 DPMEM: STA ; set the PNLMEM flag 1856 01066 7410 SKP ; fall into the regular code 1857 ; Enter here for the D command... 1858 01067 7200 DMEM: CLA ; clear the PNLMEM flag 1859 01070 3037 DCA PNLMEM ; to reference main memory 1860 1861 ; Both forms join up here... 1862 01071 6205 .PUSHJ @[RDADDR] ; Then read an address 01072 5773 1863 01073 6205 .PUSHJ @[SPATST] ; the next character has to be a space 01074 5772 1864 1865 ; Read words of data and deposit them... 1866 01075 6205 DMEM1: .PUSHJ @ZOCTNW ; read an octal operand 01076 5516 1867 01077 1065 TAD WORD ; get the data we found 1868 01100 6205 .PUSHJ @ZDANDV ; write and verify it 01101 5523 1869 01102 6205 .PUSHJ @ZNXTADR ; advance to the next address 01103 5521 1870 01104 6205 .PUSHJ @ZSPACM0 ; get the break character from OCTNW 01105 5511 1871 01106 7450 SNA ; was it the end of the line ?? 1872 01107 6225 .POPJ ; yes, we're done... 1873 01110 1374 TAD [-","] ; no - it has to be a comma otherwise 1874 01111 7640 SZA CLA ; ???? 1875 01112 5525 JMP @ZCOMERR ; bad command 1876 01113 5275 JMP DMEM1 ; go read and deposit another word PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 39 ER and DR Commands - Examine and Deposit in Registers BTS6120.PLX 1877 .TITLE ER and DR Commands - Examine and Deposit in Registers 1878 1879 1880 ; The ER command examines either a single register, when the register name 1881 ; is given as an argument, or all registers when no argument is given. For 1882 ; example: 1883 ; 1884 ; >ER AC - examine the AC 1885 ; >ER PC - examine the PC 1886 ; >ER - print all registers 1887 ; 1888 01114 6205 EREG: .PUSHJ @ZSPACMP ; get the next non-space character 01115 5510 1889 01116 7650 SNA CLA ; is it the end of line? 1890 01117 5771 JMP @[REGLSC] ; yes - type all registers and return 1891 01120 6205 .PUSHJ @ZBACKUP ; nope - backup the command scanner 01121 5512 1892 01122 6205 .PUSHJ @[NAMENW] ; and go read the register name 01123 5770 1893 01124 6205 .PUSHJ @ZEOLNXT ; now we have to be at the end of line 01125 5514 1894 01126 1367 TAD [ENAMES-1] ; point to the name table 1895 01127 6205 .PUSHJ @[MATCH] ; find it and call a routine to print 01130 5766 1896 01131 5506 JMP @ZCRLF ; finish the line and we're done 1897 1898 ; The DR command deposits a value in a register, and both a register name and 1899 ; an octal value are required arguments. For example: 1900 ; 1901 ; >DR AC 7777 - set the AC to 7777 1902 ; >DR SR 3345 - set the switch register to 3345 1903 ; 1904 01132 6205 DREG: .PUSHJ @[NAMENW] ; get the register name 01133 5770 1905 01134 6205 .PUSHJ @[SPANXT] ; the terminator has to be a space 01135 5765 1906 01136 6205 .PUSHJ @ZOCTNW ; read an octal number to deposit 01137 5516 1907 01140 6205 .PUSHJ @ZEOLTST ; followed by the end of the line 01141 5513 1908 01142 1364 TAD [DNAMES-1] ; point to the list of deposit names 1909 01143 5766 JMP @[MATCH] ; call the right routine and we're done 1910 01164 3357 01165 6121 01166 6642 01167 3343 01170 6600 01171 1240 01172 6123 01173 6416 01174 7724 01175 1060 01176 6400 01177 7770 1911 01200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 40 Deposit in Registers BTS6120.PLX 1912 .TITLE Deposit in Registers 1913 1914 1915 ; Here to deposit in the AC... 1916 01200 1065 DAC: TAD WORD ; Get his value 1917 01201 3001 DCA UAC ; And change the AC 1918 01202 6225 .POPJ ; Then that's all 1919 1920 ; Here to deposit in the PC... 1921 01203 1065 DPC: TAD WORD ; The same old routine... 1922 01204 3000 DCA UPC ; ... 1923 01205 5777 JMP @[EXMEM] ; sync the display with the new PC 1924 1925 ; Here to deposit in the MQ... 1926 01206 1065 DMQ: TAD WORD ; ... 1927 01207 3003 DCA UMQ ; ... 1928 01210 6225 .POPJ ; ... 1929 1930 ; Here to deposit in the PS... 1931 01211 1065 DPS: TAD WORD ; ... 1932 01212 0376 AND [6277] ; only these bits can actually change 1933 01213 7421 MQL ; save the new value for a minute 1934 01214 1002 TAD UFLAGS ; get the current status 1935 01215 0375 AND [1500] ; clear the complementary bits 1936 01216 7501 MQA ; or everything together 1937 01217 3002 DCA UFLAGS ; and update the PS 1938 01220 5777 JMP @[EXMEM] ; sync the display with the new IF 1939 1940 ; Here to deposit in the switch register... 1941 01221 1065 DSR: TAD WORD ; ... 1942 01222 6246 WSR ; Load the switch register 1943 01223 6225 .POPJ ; Then that's all 1944 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 41 Examine Registers BTS6120.PLX 1945 .TITLE Examine Registers 1946 1947 1948 ; This routine is called to type out all the important internal registers. 1949 ; It is used by the ER, and SI commands, and after breakpoints, traps and 1950 ; halts. 1951 01224 7200 REGLST: CLA ; be sure the AC is cleared 1952 01225 6205 .PUSHJ TYPEPC ; type the PC first 01226 5255 1953 01227 6205 .PUSHJ TYPEPS ; then the LINK 01230 5265 1954 01231 6205 .PUSHJ TYPEAC ; then the AC 01232 5252 1955 01233 6205 .PUSHJ TYPEMQ ; then the MQ 01234 5260 1956 01235 6205 .PUSHJ TYPSP1 ; user stack pointer 1 01236 5270 1957 01237 5273 JMP TYPSP2 ; and finally stack pointer 2 1958 1959 ; The same as REGLST, but with a carriage return added... 1960 01240 6205 REGLSC: .PUSHJ REGLST ; first type the registers 01241 5224 1961 01242 5506 JMP @ZCRLF ; type the carriage return and we're done 1962 1963 ; This routine types a register name followed by an octal register value. 1964 ; The latter is passed in the AC, and the register name is passed inline. 1965 01243 0000 TYPRG4: 0 ; enter here with a JMS instruction 1966 01244 3044 DCA VALUE ; save the register contents for a moment 1967 01245 1643 TAD @TYPRG4 ; and get the address of the register name 1968 01246 6205 .PUSHJ @[OUTSTR] ; type that 01247 5774 1969 01250 1044 TAD VALUE ; get the contents of the register 1970 01251 5502 JMP @ZTOCT4S ; type that in octal and leave a blank 1971 1972 ; This routine will type the last user AC contents... 1973 01252 1001 TYPEAC: TAD UAC ; get the contents of the register 1974 01253 4243 JMS TYPRG4 ; type it and return 1975 01254 3711 ACNAME ; "AC>" 1976 1977 ; This routine will type the last user PC... 1978 01255 1000 TYPEPC: TAD UPC ; the same old routine... 1979 01256 4243 JMS TYPRG4 ; ... 1980 01257 3714 PCNAME ; "PC>" 1981 1982 ; This routine will type the last user MQ contents... 1983 01260 1003 TYPEMQ: TAD UMQ ; ... 1984 01261 4243 JMS TYPRG4 ; ... 1985 01262 3717 MQNAME ; "MQ>" 1986 1987 ; This routine will type the last instruction executed... 1988 01263 6222 TYPEIR: CIF 2 1989 01264 5773 JMP @[XTYPIR] 1990 1991 ; This routine will type the current interrupt flags... 1992 01265 1002 TYPEPS: TAD UFLAGS ; get the flags 1993 01266 4243 JMS TYPRG4 ; ... 1994 01267 3730 PSNAME ; "PS>" 1995 1996 ; This routine will type the 6120 stack pointer #1... 1997 01270 1004 TYPSP1: TAD USP1 ; ... 1998 01271 4243 JMS TYPRG4 ; ... 1999 01272 3733 SP1NAM ; "SP1>" 2000 2001 ; This routine will type the 6120 stack pointer #2... 2002 01273 1005 TYPSP2: TAD USP2 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 42 Examine Registers BTS6120.PLX 2003 01274 4243 JMS TYPRG4 ; ... 2004 01275 3737 SP2NAM ; "SP2>" 2005 2006 ; This routine will type the current switch register contents... 2007 01276 7604 TYPESR: LAS ; actually read the switch register 2008 01277 4243 JMS TYPRG4 ; ... 2009 01300 3725 SRNAME ; "SR>" PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 43 Read and Write Memory BTS6120.PLX 2010 .TITLE Read and Write Memory 2011 2012 2013 ; This routine will change the current data field to the field indicated in 2014 ; location ADRFLD. It's normally used by commands that read or write memory, 2015 ; such as Examine, Deposit, etc. Remember that on the 6120 the EMA works in 2016 ; panel memory as well, so don't forget to change back to field zero after 2017 ; you're done! 2018 01301 7200 CFIELD: CLA ; ... 2019 01302 1036 TAD ADRFLD ; get the desired field number 2020 01303 0131 AND ZK70 ; just in case! 2021 01304 1372 TAD [CDF 0] ; and make a CDF instruction 2022 01305 3306 DCA .+1 ; store that in memory 2023 01306 0000 0 ; isn't self manipulation wonderful? 2024 01307 6225 .POPJ ; that's all 2025 2026 ; This routine will set or clear the panel data flag according to the state 2027 ; of the PNLMEM flag. If PNLMEM is non-zero, the panel data flag is set and 2028 ; commands that access memory (e.g. Examine, Deposit, etc) access panel memory 2029 ; instead. If PNLMEM is zero, then the panel data flag is cleared and these 2030 ; commands access main memory. 2031 01310 7200 CPANEL: CLA ; don't expect anything from the caller 2032 01311 6276 SPD ; assume we're referencing panel memory 2033 01312 1037 TAD PNLMEM ; but get the flag to be sure 2034 01313 7650 SNA CLA ; non-zero means access panel memory 2035 01314 6266 CPD ; we were wrong - use main memory instead 2036 01315 6225 .POPJ ; and we're done 2037 2038 ; This short routine returns, in the AC and memory location VALUE, the 2039 ; contents of the memory location addressed by ADDR and ADRFLD. If PNLMEM is 2040 ; non-zero it reads panel memory to get the data; otherwise it reads main 2041 ; memory... 2042 01316 6205 RDMEM: .PUSHJ CFIELD ; first select the proper field 01317 5301 2043 01320 6205 .PUSHJ CPANEL ; then select main memory or panel memory 01321 5310 2044 01322 1435 TAD @ADDR ; load the data 2045 01323 3044 DCA VALUE ; save the contents in VALUE 2046 01324 1044 TAD VALUE ; and also return it in the AC 2047 01325 6276 SPD ; back to panel memory 2048 01326 6201 CDF 0 ; and back to the monitor's field 2049 01327 6225 .POPJ ; that's all there is 2050 2051 ; This routine will deposit the contents of the AC into the memory location 2052 ; specified by ADRFLD, ADDR and PNLMEM. It's the complement of RDMEM... 2053 01330 3044 WRMEM: DCA VALUE ; save the number to deposit 2054 01331 6205 .PUSHJ CFIELD ; be sure we're in the right field 01332 5301 2055 01333 6205 .PUSHJ CPANEL ; and the right memory space (panel vs main) 01334 5310 2056 01335 1044 TAD VALUE ; get the value back again 2057 01336 3435 DCA @ADDR ; store the data 2058 01337 6276 SPD ; back to panel memory 2059 01340 6201 CDF 0 ; and the monitor's data field 2060 01341 6225 .POPJ ; and return 2061 2062 ; This routine is just like WRMEM, except that it will read back the value 2063 ; deposited and verify that it is, in fact, correct! If it isn't (i.e. there's 2064 ; no memory at that address or the memory there isn't working) a ?MEM ERR 2065 ; message is generated and this command is aborted. 2066 01342 3367 DANDV: DCA GOOD ; save the original, good, value 2067 01343 1367 TAD GOOD ; ... 2068 01344 6205 .PUSHJ WRMEM ; store it 01345 5330 2069 01346 6205 .PUSHJ RDMEM ; read it back PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 44 Read and Write Memory BTS6120.PLX 01347 5316 2070 01350 7041 CIA ; make what we read negative 2071 01351 1367 TAD GOOD ; and compare it to the desired value 2072 01352 7650 SNA CLA ; did they match ?? 2073 01353 6225 .POPJ ; yes -- this memory is ok 2074 2075 ; Type a "?MEM ERR AT faaaa ..." message 2076 01354 4507 JMS @ZINLMES ; type out the first part of the message 2077 01355 3413 MEMMSG ; ... 2078 01356 6205 .PUSHJ @[TADDR] ; then type the address of the error 01357 5771 2079 01360 1367 TAD GOOD ; get the expected value 2080 01361 6205 .PUSHJ @ZTOCT4S ; type that out first 01362 5502 2081 01363 6205 .PUSHJ @ZRDMEM ; read what we actually get from memory 01364 5522 2082 01365 6205 .PUSHJ @ZTOCT4M ; then type that with a CRLF 01366 5501 2083 2084 ; Temporary storage for DANDV... 2085 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 2086 01400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 45 BM Command -- Memory Block Move BTS6120.PLX 2087 .TITLE BM Command -- Memory Block Move 2088 2089 2090 ; The BM command is used to move blocks of memory words from one location to 2091 ; another. It has three parameters - the source address range (two 15 bit 2092 ; numbers), and the destination address (a single 15 bit number). All words 2093 ; from the starting source address to the ending source address are transferred 2094 ; to the corresponding words starting at the destination address. More than 2095 ; one field may be transferred, and transfers may cross a field boundry. 2096 ; 2097 ; >BM 200-377 400 -> move all of page 1 in the current data field 2098 ; to page 2 of the same field. 2099 ; >BM 0-7777 10000 -> move all of field 0 to field 1 2100 ; >BM 00000-37777 40000 -> move fields 0 thru 3 to fields 4 thru 7 2101 ; 2102 ; Note that this command operates only on main memory - there is no 2103 ; corresponding block move command for panel memory! 2104 ; 2105 01400 6205 BMOVE: .PUSHJ @ZRANGE ; read the source address range 01401 5517 2106 01402 7420 SNL ; did he give 2 numbers ??? 2107 01403 5525 JMP @ZCOMERR ; no -- don't allow a one address range 2108 01404 6205 .PUSHJ @[RDADDR] ; now read the destination 01405 5777 2109 01406 6205 .PUSHJ @ZEOLTST ; this should be the end of the command 01407 5513 2110 01410 3037 DCA PNLMEM ; this command ALWAYS operates on main memory 2111 2112 ; Now copy words from the source to the destination... 2113 01411 6205 MOVE1: .PUSHJ @[SWPADR] ; swap the LOW/LOWFLD (the source address) 01412 5776 2114 01413 6205 .PUSHJ @ZRDMEM ; read a word from the source 01414 5522 2115 01415 6205 .PUSHJ @ZTSTADR ; go see if this is the last address 01416 5520 2116 01417 7630 SZL CLA ; is it the end ??? 2117 01420 7240 STA ; yes -- load -1 into the AC 2118 01421 3067 DCA COUNT ; and remember that fact for later 2119 01422 6205 .PUSHJ @ZNXTADR ; now increment the source address 01423 5521 2120 01424 6205 .PUSHJ @[SWPADR] ; swap the source back into LOW/LOWFLD 01425 5776 2121 01426 1044 TAD VALUE ; get the data we read from the source 2122 01427 6205 .PUSHJ @ZDANDV ; and deposit it in the destination 01430 5523 2123 01431 6205 .PUSHJ @ZNXTADR ; increment the destination address too 01432 5521 2124 01433 7430 SZL ; did we wrap out of field 7 ??? 2125 01434 5240 JMP MOVE2 ; yes -- stop here 2126 01435 2067 ISZ COUNT ; have we copied all the words ?? 2127 01436 5211 JMP MOVE1 ; no -- keep looping 2128 01437 6225 .POPJ ; yes -- that's all 2129 2130 ; Here if the destination address runs out of field 7... 2131 01440 4526 MOVE2: JMS @ZERROR ; don't allow that to continue 2132 01441 3464 ERRWRP ; ?WRAP AROUND PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 46 CK Command -- Checksum Memory BTS6120.PLX 2133 .TITLE CK Command -- Checksum Memory 2134 2135 2136 ; This command will compute the checksum of all memory locations between the 2137 ; two addresses specified and the resulting 12 bit value is then printed 2138 ; on the terminal. This is useful for testing memory, comparing blocks of 2139 ; memory, and so on. Note that the checksum algorithm used rotates the 2140 ; accumulator one bit between each words, so blocks of memory with identical 2141 ; contents in different orders will give different results. 2142 ; 2143 ; >CK 10000-10177 -> checksum all of page 0, field 1 2144 ; 2145 ; Note that this command operates only on main memory - there is no 2146 ; corresponding command for panel memory! 2147 01442 6205 CKMEM: .PUSHJ @ZRANGE ; read a two address range 01443 5517 2148 01444 7420 SNL ; two addresses are required 2149 01445 5525 JMP @ZCOMERR ; ... 2150 01446 6205 .PUSHJ @ZEOLTST ; be sure this is the end of the command 01447 5513 2151 01450 3037 DCA PNLMEM ; this command ALWAYS operates on main memory 2152 01451 3046 DCA CHKSUM ; and clear the checksum accumulator 2153 2154 ; Read words and checksum them... 2155 01452 1046 CKMEM1: TAD CHKSUM ; get the previous total 2156 01453 7104 CLL RAL ; and shift it left one bit 2157 01454 7430 SZL ; did we shift out a one ?? 2158 01455 7001 IAC ; yes -- shift it in the right end 2159 01456 3046 DCA CHKSUM ; save that for a while 2160 01457 6205 .PUSHJ @ZRDMEM ; and go read a word from real memory 01460 5522 2161 01461 1046 TAD CHKSUM ; add it to the checksum 2162 01462 3046 DCA CHKSUM ; save the new checksum 2163 01463 6205 .PUSHJ @ZTSTADR ; compare the addresses next 01464 5520 2164 01465 7430 SZL ; are we all done ?? 2165 01466 5277 JMP TCKSUN ; yes -- type the checksum and return 2166 01467 6205 .PUSHJ @ZNXTADR ; no -- increment the address 01470 5521 2167 01471 5252 JMP CKMEM1 ; and proceed 2168 2169 ; This routine will type out the checksum currently contained in location 2170 ; CHKSUM. If the checksum isn't zero, it will type a question mark (making 2171 ; a pseudo error message) first... 2172 01472 1046 TCKSUM: TAD CHKSUM ; see if the checksum is zero 2173 01473 7650 SNA CLA ; ??? 2174 01474 5277 JMP TCKSUN ; yes -- type it normally 2175 01475 6205 .PUSHJ @[TQUEST] ; no -- type a question mark first 01476 5775 2176 2177 ; Now type the checksum... 2178 01477 4507 TCKSUN: JMS @ZINLMES ; type out the checksum message 2179 01500 3402 CKSMSG ; ... 2180 01501 1046 TAD CHKSUM ; get the actual checksum 2181 01502 5500 JMP @ZTOCT4C ; type it with a CRLF and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 47 CM and FM Commands -- Clear Memory and Fill Memory BTS6120.PLX 2182 .TITLE CM and FM Commands -- Clear Memory and Fill Memory 2183 2184 2185 ; The FM command fills a range of memory locations with a constant. For 2186 ; example: 2187 ; 2188 ; >FM 7402 0-7777 -> fill all of field zero with HLT instructions 2189 ; >FM 7777 0-77777 -> fill all of memory with -1 2190 ; 2191 ; The second and third arguments (the address range) may be omitted, in 2192 ; which case all of memory is filled. 2193 ; 2194 ; Note that this command operates only on main memory - there is no 2195 ; corresponding command for panel memory! 2196 01503 6205 FLMEM: .PUSHJ @ZOCTNW ; read the constant to fill with 01504 5516 2197 01505 1065 TAD WORD ; get the desired value 2198 01506 5312 JMP CMEM0 ; then join the CM command 2199 2200 ; The CM command is identical to FM, except that the fill value is always 2201 ; zero (hence the name - "Clear" memory). For example: 2202 ; 2203 ; >CM 50000 57777 -> clear all of field 5 2204 ; >CM -> (with no arguments) clear all of memory! 2205 ; 2206 ; Like FM, this command operates only on main memory. There is no 2207 ; equivalent for panel memory. 2208 01507 6205 CMEM: .PUSHJ @ZGET ; advance the scanner to the break character 01510 5515 2209 01511 7200 CLA ; and throw it away for now 2210 01512 3044 CMEM0: DCA VALUE ; and fill with zeros 2211 01513 3035 DCA ADDR ; initialize the address range to start 2212 01514 3036 DCA ADRFLD ; at location 0000, field 0 2213 01515 7240 STA ; and to finish at location 7777, 2214 01516 3040 DCA HIGH ; ... 2215 01517 1131 TAD ZK70 ; field 7 2216 01520 3042 DCA HGHFLD ; ... 2217 01521 3037 DCA PNLMEM ; this command ALWAYS operates on main memory 2218 2219 ; See if there is an address range... 2220 01522 6205 .PUSHJ @ZSPACM0 ; get the break character 01523 5511 2221 01524 7650 SNA CLA ; is there any more out there ?? 2222 01525 5334 JMP CMEM1 ; no -- start filling 2223 01526 6205 .PUSHJ @ZBACKUP ; yes - backup to the first character 01527 5512 2224 01530 6205 .PUSHJ @ZRANGE ; and read the address range 01531 5517 2225 01532 6205 .PUSHJ @ZEOLTST ; then check for the end of the line 01533 5513 2226 2227 ; Clear/set memory locations... 2228 01534 1044 CMEM1: TAD VALUE ; get the value to store 2229 01535 6205 .PUSHJ @ZDANDV ; store it and verify 01536 5523 2230 01537 6205 .PUSHJ @ZTSTADR ; see if we have done all the addresses 01540 5520 2231 01541 7430 SZL ; well ?? 2232 01542 6225 .POPJ ; yes -- we can stop now 2233 01543 6205 .PUSHJ @ZNXTADR ; no -- increment the address field 01544 5521 2234 01545 5334 JMP CMEM1 ; then go clear this word PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 48 X / XP Command Stubs -- Disassemble memory BTS6120.PLX 2235 .TITLE X / XP Command Stubs -- Disassemble memory 2236 2237 ; stubs in field 0 call actual functions in field 2 2238 01546 6223 DISASM: CXF 2 2239 01547 5774 JMP @[CMDX] 2240 2241 01550 6223 DISASMP: CXF 2 2242 01551 5773 JMP @[CMDXP] 2243 01573 0603 01574 0600 01575 7066 01576 6521 01577 6416 2244 01600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 49 WS Command -- Word Search Memory BTS6120.PLX 2245 .TITLE WS Command -- Word Search Memory 2246 2247 2248 ; The WS command searches memory for a specific bit pattern. It accepts up 2249 ; to 4 operands: (1) the value to search for, (2) the starting search address, 2250 ; (3) the final search address, and (4) a search mask. All values except the 2251 ; first are optional and have appropriate defaults. Any location in the 2252 ; specified range which matches the given value after being masked is typed 2253 ; out along with its address. For example: 2254 ; 2255 ; >WS 6031 -> search all of memory for KSF instructions 2256 ; >WS 6031 30000-33777 -> search words 0..3377 of field 3 for KSFs 2257 ; >WS 6030 0-77777 7770 -> search memory for any keyboard IOTs 2258 ; 2259 ; N.B. this command operates only on main memory and there is no equivalent 2260 ; for panel memory. 2261 2262 ; Read the first (required) operand and set defaults for all the rest... 2263 01600 6205 SEARCH: .PUSHJ @ZOCTNW ; read the value to search for 01601 5516 2264 01602 1065 TAD WORD ; then get that 2265 01603 3272 DCA KEY ; and save it 2266 01604 3035 DCA ADDR ; set the starting address to 0 2267 01605 3036 DCA ADRFLD ; in field 0 2268 01606 7240 STA ; then stop at location 7777 2269 01607 3040 DCA HIGH ; ... 2270 01610 1131 TAD ZK70 ; field 7 2271 01611 3042 DCA HGHFLD ; ... 2272 01612 7240 STA ; and set the mask to 7777 2273 01613 3273 DCA MASK ; ... 2274 01614 3037 DCA PNLMEM ; this command _always_ searches main memory 2275 2276 ; Try to read any optional operands... 2277 01615 1050 TAD SAVCHR ; is there any more there ?? 2278 01616 7650 SNA CLA ; ??? 2279 01617 5233 JMP SEAR1 ; no -- start looking 2280 01620 6205 .PUSHJ @ZRANGE ; yes -- read the address range 01621 5517 2281 01622 1050 TAD SAVCHR ; is there a mask out there ?? 2282 01623 7650 SNA CLA ; ??? 2283 01624 5233 JMP SEAR1 ; no -- start looking 2284 01625 6205 .PUSHJ @ZOCTNW ; yes -- read the mask too 01626 5516 2285 01627 1065 TAD WORD ; load the mask 2286 01630 3273 DCA MASK ; and save that for later 2287 01631 6205 .PUSHJ @ZEOLTST ; this has to be the end of the line 01632 5513 2288 2289 ; Here to start the search... 2290 01633 3067 SEAR1: DCA COUNT ; count the number of matches we find 2291 01634 1272 TAD KEY ; get the search key 2292 01635 0273 AND MASK ; apply the mask to it too 2293 01636 7041 CIA ; make it negative 2294 01637 3272 DCA KEY ; and remember that instead 2295 2296 ; Look through memory for matches... 2297 01640 6205 SEAR2: .PUSHJ @[INCHRS] ; poll the operator for control-C 01641 5777 2298 01642 6205 .PUSHJ @ZRDMEM ; read a word from real memory 01643 5522 2299 01644 0273 AND MASK ; apply the mask to it 2300 01645 1272 TAD KEY ; and compare to the value 2301 01646 7640 SZA CLA ; does it match ?? 2302 01647 5256 JMP SEAR3 ; no -- skip it 2303 01650 6205 .PUSHJ @[TMEM] ; yes -- type the address and contents PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 50 WS Command -- Word Search Memory BTS6120.PLX 01651 5776 2304 01652 6205 .PUSHJ @ZCRLF ; then finish the line 01653 5506 2305 01654 7240 STA ; make the AC non-zero 2306 01655 3067 DCA COUNT ; and remember that we found a match 2307 01656 6205 SEAR3: .PUSHJ @ZTSTADR ; see if we have looked everywhere 01657 5520 2308 01660 7430 SZL ; well ?? 2309 01661 5265 JMP SEAR4 ; yes -- finish up now 2310 01662 6205 .PUSHJ @ZNXTADR ; no -- increment the address 01663 5521 2311 01664 5240 JMP SEAR2 ; and keep looking 2312 2313 ; Here at the end of the search... 2314 01665 1067 SEAR4: TAD COUNT ; see how many matches there were 2315 01666 7640 SZA CLA ; were there any at all ?? 2316 01667 6225 .POPJ ; yes -- that's fine 2317 01670 4526 JMS @ZERROR ; no -- give an error message 2318 01671 3442 ERRSRF ; ? SEARCH FAILS 2319 2320 ; Temporary storage for the SEARCH routine... 2321 01672 KEY: .BLOCK 1 ; a search key 2322 01673 MASK: .BLOCK 1 ; a search mask 2323 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 51 BL Command -- List Breakpoints BTS6120.PLX 2324 .TITLE BL Command -- List Breakpoints 2325 2326 2327 ; This command will list all the breakpoints which are currently set in 2328 ; the user's program. It has no operands... 2329 ; 2330 ; >BL 2331 ; 2332 01674 6205 BLIST: .PUSHJ @ZEOLNXT ; there should be no more 01675 5514 2333 01676 6205 .PUSHJ BSETUP ; set up X1, X2 and COUNT 01677 5324 2334 01700 3044 DCA VALUE ; count the number of breakpoints here 2335 2336 ; Loop through the breakpoint table and list all valid breakpoints... 2337 01701 1410 BLIST1: TAD @X1 ; get the address of this breakpoint 2338 01702 3035 DCA ADDR ; and remember that 2339 01703 1411 TAD @X2 ; then get the corresponding field 2340 01704 3036 DCA ADRFLD ; ... 2341 01705 1035 TAD ADDR ; let's see that address again 2342 01706 7650 SNA CLA ; is there really a breakpoint set here ?? 2343 01707 5315 JMP BLIST2 ; no -- on to the next one 2344 01710 6205 .PUSHJ @[TMEM] ; yes -- type out the address and memory 01711 5776 2345 01712 6205 .PUSHJ @ZCRLF ; finish this line 01713 5506 2346 01714 2044 ISZ VALUE ; and count the number we find 2347 01715 2067 BLIST2: ISZ COUNT ; are there more breakpoints to do? 2348 01716 5301 JMP BLIST1 ; yes - keep going 2349 2350 ; Here after going through the table... 2351 01717 1044 TAD VALUE ; see how many we found 2352 01720 7640 SZA CLA ; any at all ?? 2353 01721 6225 .POPJ ; yes -- that's great 2354 01722 4526 JMS @ZERROR ; no -- print an error message 2355 01723 3653 ERRNBP ; ?NONE SET 2356 2357 ; This routine will set up the pointers for traversing the break point 2358 ; table. X1 always points to the break point address table, X2 points to 2359 ; the break point field table, and X3 points to the break point data table. 2360 ; COUNT is initialized to the negative of the table size (all three tables 2361 ; are the same size) so that it can be used as an ISZ counter. This same 2362 ; arrangement of pointers is used by all the routines that operate on 2363 ; breakpoints. 2364 01724 7200 BSETUP: CLA ; just in case... 2365 01725 1375 TAD [BPTADR-1] ; X1 points to the address table 2366 01726 3010 DCA X1 ; ... 2367 01727 1374 TAD [BPTFLD-1] ; X2 points to the field table 2368 01730 3011 DCA X2 ; ... 2369 01731 1373 TAD [BPTDAT-1] ; X3 points to the data table 2370 01732 3012 DCA X3 ; ... 2371 01733 1372 TAD [-MAXBPT] ; and COUNT is the table size 2372 01734 3067 DCA COUNT ; ... 2373 01735 3037 DCA PNLMEM ; break points always refer to main memory! 2374 01736 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 52 Search for Breakpoints BTS6120.PLX 2375 .TITLE Search for Breakpoints 2376 2377 2378 ; This routine will search the breakpoint table to see if there is a one set 2379 ; at the location specified by ADDR and ADRFLD. If one is found, it will 2380 ; return with the LINK set and with X1/X2 pointing to the table entry. If 2381 ; there is no breakpoint at the specified address, it returns with the LINK 2382 ; cleared. 2383 01737 6205 BPTFND: .PUSHJ BSETUP ; set up X1, X2 and COUNT 01740 5324 2384 2385 ; Look through the entire table... 2386 01741 1410 BPTFN1: TAD @X1 ; get this breakpoint address 2387 01742 7450 SNA ; is there breakpoint here at all ?? 2388 01743 5357 JMP BPTFN2 ; no -- just forget it 2389 01744 7041 CIA ; make this address negative 2390 01745 1035 TAD ADDR ; and compare to what we want 2391 01746 7640 SZA CLA ; does it match ?? 2392 01747 5357 JMP BPTFN2 ; no -- on to the next one 2393 01750 1411 TAD @X2 ; yes -- get the field number 2394 01751 7041 CIA ; make that negative 2395 01752 1036 TAD ADRFLD ; and compare to the field we need 2396 01753 7640 SZA CLA ; do they match to ?? 2397 01754 5360 JMP BPTFN3 ; no -- keep looking 2398 01755 7120 STL ; yes -- set the LINK 2399 01756 6225 .POPJ ; and stop right now 2400 2401 ; Here if the current address dosen't match... 2402 01757 2011 BPTFN2: ISZ X2 ; increment the field pointer too 2403 01760 2067 BPTFN3: ISZ COUNT ; have we searched the entire table? 2404 01761 5341 JMP BPTFN1 ; no -- keep looking 2405 01762 7100 CLL ; yes -- clear the LINK 2406 01763 6225 .POPJ ; and return 2407 01772 7770 01773 0220 01774 0210 01775 0200 01776 1060 01777 7477 2408 02000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 53 BR Command -- Remove Breakpoints BTS6120.PLX 2409 .TITLE BR Command -- Remove Breakpoints 2410 2411 2412 ; The BR command removes a breakpoint at a specific address or, if no 2413 ; operand is given, removes all breakpoints. For example: 2414 ; 2415 ; >BR 17605 -> remove the breakpoint at location 7605, field 1 2416 ; >BR -> remove all breakpoints regardless of address 2417 ; 2418 02000 6205 BREMOV: .PUSHJ @ZGET ; get the next character 02001 5515 2419 02002 7650 SNA CLA ; is it the end of the line ?? 2420 02003 5226 JMP BPTCLR ; yes -- clear all breakpoints 2421 02004 6205 .PUSHJ @ZBACKUP ; no -- backup the scanner 02005 5512 2422 02006 6205 .PUSHJ @[OCTNI] ; then read an address 02007 5777 2423 02010 1065 TAD WORD ; get the breakpoint address 2424 02011 7450 SNA ; be sure it isn't location zero 2425 02012 5525 JMP @ZCOMERR ; that isn't legal 2426 02013 3035 DCA ADDR ; save the address of the breakpoint 2427 2428 ; Here to remove a single breakpoint... 2429 02014 6205 .PUSHJ @[BPTFND] ; look for this breakpoint it the table 02015 5776 2430 02016 7420 SNL ; did we find it ?? 2431 02017 5224 JMP BREMO1 ; no -- there's no breakpoint at that address 2432 02020 1010 TAD X1 ; yes -- get the pointer to BPTADR 2433 02021 3035 DCA ADDR ; and save it in a non-autoindex location 2434 02022 3435 DCA @ADDR ; clear the BPTADR entry (to remove it) 2435 02023 6225 .POPJ ; and that's all 2436 2437 ; Here if the breakpoint does not exist... 2438 02024 4526 BREMO1: JMS @ZERROR ; give an appropriate error message 2439 02025 3662 ERRNST ; ?NOT SET 2440 2441 ; Here to clear all breakpoints... 2442 02026 6205 BPTCLR: .PUSHJ @[BSETUP] ; setup X1, X2, X3 and COUNT 02027 5775 2443 02030 3410 BPTCL2: DCA @X1 ; clear this breakpoint 2444 02031 3411 DCA @X2 ; ... 2445 02032 3412 DCA @X3 ; ... 2446 02033 2067 ISZ COUNT ; have we done them all? 2447 02034 5230 JMP BPTCL2 ; no -- keep looping 2448 02035 6225 .POPJ ; yes -- that's it PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 54 BP Command -- Set Breakpoints BTS6120.PLX 2449 .TITLE BP Command -- Set Breakpoints 2450 2451 2452 ; The BP command sets a breakpoint in the main memory (aka user) program. 2453 ; It requires a single argument giving the 15 bit address where the breakpoint 2454 ; is to be set. For example: 2455 ; 2456 ; >BP 07605 -> set a breakpoint at location 7605, field 0 2457 ; >BP 7605 -> same, but in the current instruction field 2458 ; 2459 ; It's not possible to set a breakpoint at location zero in any field because 2460 ; the monitor uses zero as a marker for an unused breakpoint table entry. 2461 ; 2462 ; Note that this routine only enters the breakpoint into the table - nothing 2463 ; actually happens to the main memory program until we start running it and 2464 ; the BPTINS routine is called. 2465 02036 6205 BPTCOM: .PUSHJ @[OCTNI] ; go read the address 02037 5777 2466 02040 1065 TAD WORD ; get the address operand 2467 02041 7450 SNA ; be sure it isn't zero 2468 02042 5525 JMP @ZCOMERR ; no breakpoints at address zero 2469 02043 3035 DCA ADDR ; and put it in a safe place 2470 02044 6205 .PUSHJ @ZEOLTST ; then test for the end of the line 02045 5513 2471 2472 ; See if this breakpoint is already in the table.. 2473 02046 6205 .PUSHJ @[BPTFND] ; ... 02047 5776 2474 02050 7620 SNL CLA ; was it found ?? 2475 02051 5254 JMP BPTCO1 ; no -- go try to add it 2476 02052 4526 JMS @ZERROR ; yes -- say that it is already set 2477 02053 3670 ERRAST ; ?ALREADY SET 2478 2479 ; Here to search for a free location in the table... 2480 02054 6205 BPTCO1: .PUSHJ @[BSETUP] ; setup X1 and COUNT 02055 5775 2481 02056 2011 BPTCO2: ISZ X2 ; keep X1 and X2 in sync 2482 02057 1410 TAD @X1 ; get this table entry 2483 02060 7650 SNA CLA ; have we found an empty one ?? 2484 02061 5266 JMP BPTCO3 ; yes -- great 2485 02062 2067 ISZ COUNT ; have we searched the entire table? 2486 02063 5256 JMP BPTCO2 ; no -- keep trying 2487 02064 4526 JMS @ZERROR ; yes -- say that the table is full 2488 02065 3701 ERRBTF ; ?TABLE FULL 2489 2490 ; Here to insert the breakpoint in the table... 2491 02066 1010 BPTCO3: TAD X1 ; get the pointer to the free location 2492 02067 3041 DCA LOW ; and put it in a non-autoindex location 2493 02070 1035 TAD ADDR ; get the desired address 2494 02071 3441 DCA @LOW ; and store that in the table 2495 02072 1011 TAD X2 ; do the same with the field table 2496 02073 3041 DCA LOW ; ... 2497 02074 1036 TAD ADRFLD ; get the field we need 2498 02075 3441 DCA @LOW ; and put that in the table 2499 02076 6225 .POPJ ; then that's all PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 55 Insert Breakpoints in Memory BTS6120.PLX 2500 .TITLE Insert Breakpoints in Memory 2501 2502 2503 ; This routine will insert breakpoints in main memory (aka the user program) 2504 ; at the locations specified in the breakpoint table. The current contents of 2505 ; each breakpoint location are stored in CP memory in the BPTDAT table, and 2506 ; then are replaced by a BPT instruction. This routine is normally called 2507 ; just before returning control to the user's program. 2508 02077 6205 BPTINS: .PUSHJ @[BSETUP] ; set up X1, X2, X3 and COUNT 02100 5775 2509 2510 ; Loop through the table and insert the breakpoints... 2511 02101 1410 BPTIN1: TAD @X1 ; get the next address 2512 02102 7450 SNA ; is there a breakpoint set there ?? 2513 02103 5316 JMP BPTIN2 ; no -- proceed to the next one 2514 02104 3035 DCA ADDR ; yes -- save the address 2515 02105 1411 TAD @X2 ; and get the field 2516 02106 3036 DCA ADRFLD ; save that too 2517 02107 6205 .PUSHJ @ZRDMEM ; go read the contents of that location 02110 5522 2518 02111 3412 DCA @X3 ; save the user's data in the table 2519 02112 1374 TAD [BPT] ; then get a breakpoint instruction 2520 02113 6205 .PUSHJ @ZDANDV ; deposit that in the breakpoint location 02114 5523 2521 02115 5320 JMP BPTIN3 ; proceed to the next one 2522 2523 ; See if we have finished the table... 2524 02116 2011 BPTIN2: ISZ X2 ; keep the pointers in sync 2525 02117 2012 ISZ X3 ; ... 2526 02120 2067 BPTIN3: ISZ COUNT ; have we been all the way through ?? 2527 02121 5301 JMP BPTIN1 ; no -- keep going 2528 02122 6225 .POPJ ; yes -- quit now PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 56 Remove Breakpoints from Memory BTS6120.PLX 2529 .TITLE Remove Breakpoints from Memory 2530 2531 2532 ; This routine will restore the original contents of all breakpoint locations 2533 ; in the main memory program from the table at BPTDAT. It is normally called 2534 ; after a trap to CP memory occurs. Breakpoints must be restored so that the 2535 ; user may examine or change them. 2536 02123 6205 BPTRMV: .PUSHJ @[BSETUP] ; set up X1, X2, X3 and COUNT 02124 5775 2537 2538 ; Loop through the breakpoint table and restore all data... 2539 02125 1410 BPTRM1: TAD @X1 ; get the address of this breakpoint 2540 02126 7450 SNA ; is there one there at all ?? 2541 02127 5337 JMP BPTRM2 ; no -- on to the next one 2542 02130 3035 DCA ADDR ; yes -- remember the address 2543 02131 1411 TAD @X2 ; then get the correct field too 2544 02132 3036 DCA ADRFLD ; ... 2545 02133 1412 TAD @X3 ; finally get the original contents 2546 02134 6205 .PUSHJ @ZDANDV ; deposit and verify it back where it goes 02135 5523 2547 02136 5341 JMP BPTRM3 ; on to the next one 2548 2549 ; Here to advance to the next breakpoint... 2550 02137 2011 BPTRM2: ISZ X2 ; keep the pointers in sync 2551 02140 2012 ISZ X3 ; ... 2552 02141 2067 BPTRM3: ISZ COUNT ; have we done them all ?? 2553 02142 5325 JMP BPTRM1 ; no -- keep looping 2554 02143 6225 .POPJ ; yes -- that's it for this time PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 57 TR Command -- Single Instruction with Trace BTS6120.PLX 2555 .TITLE TR Command -- Single Instruction with Trace 2556 2557 2558 ; The TR command will execute one instruction of the user's program and then 2559 ; print the registers. It always executes one instruction, but it may be 2560 ; combined with the repeat (RP) command to execute multiple instructions. 2561 02144 6205 SICOM: .PUSHJ @ZEOLNXT ; there are no operands 02145 5514 2562 2563 ; Figure out what we are going to execute... 2564 02146 1002 TRACE: TAD UFLAGS ; get the instruction field 2565 02147 0131 AND ZK70 ; ... 2566 02150 3036 DCA ADRFLD ; so we can change to that field 2567 02151 1000 TAD UPC ; get the current main memory PC 2568 02152 3035 DCA ADDR ; and point to that 2569 02153 1000 TAD UPC ; also save a copy for the disassember 2570 02154 3006 DCA UIRPC ; to print 2571 02155 3037 DCA PNLMEM ; always access main memory 2572 02156 6205 .PUSHJ @ZRDMEM ; go read what we're about to execute 02157 5522 2573 02160 3007 DCA UIR ; remember that for later 2574 2575 ; Execute 1 instruction... 2576 02161 6205 .PUSHJ @[SINGLE] ; just like it says 02162 5773 2577 2578 ; Print all the registers... 2579 02163 6205 .PUSHJ @[TYPEIR] ; first type the UIR 02164 5772 2580 02165 5771 JMP @[REGLSC] ; and then print the rest and return 2581 02171 1240 02172 1263 02173 2202 02174 6236 02175 1724 02176 1737 02177 7000 2582 02200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 58 SI and P Commands - Single Instruction and Proceed BTS6120.PLX 2583 .TITLE SI and P Commands - Single Instruction and Proceed 2584 2585 2586 ; This routine will execute a single instruction of the user's program and 2587 ; then return to the caller. It is used directly to execute the SI command, 2588 ; and indirectly by many other commands... 2589 2590 ; Here for the SI command... 2591 02200 6205 SNCOM: .PUSHJ @ZEOLNXT ; make sure that there is no more 02201 5514 2592 2593 ; Setting the HALT flip flop will cause the HM6120 to immediately trap back 2594 ; to panel mode after it has executed exactly one instruction of the main 2595 ; memory program. This makes it easy to implement a single step function. 2596 ; 2597 ; Note that SINGLE is a subroutine which you can actually call, via a 2598 ; .PUSHJ, from anywhere in the monitor and it will return after the main 2599 ; memory instruction has been executed. This little bit of magic happens 2600 ; because the code at CONT1 saves the monitor stack and then restores 2601 ; it after the single instruction trap. 2602 02202 6003 SINGLE: PGO ; first make sure the HALT flip flop is cleared 2603 02203 7402 HLT ; then make sure it's set 2604 02204 7240 STA ; set the software single step flag 2605 02205 3047 DCA SIMFLG ; ... so that CPSAVE will know what to do 2606 02206 5227 JMP CONT1 ; then restore the registers and go 2607 2608 ; The P command is used to proceed after the main memory program has stopped 2609 ; at a breakpoint. You can't simply continue at this point because the PC 2610 ; points to the location of the breakpoint, and Continue would simply break 2611 ; again, instantly. The Proceed command gets around this problem by first 2612 ; executing a single instruction, and then contining normally. 2613 02207 6205 PROCEE: .PUSHJ @ZEOLNXT ; this command has no operands 02210 5514 2614 02211 6205 .PUSHJ SINGLE ; first execute the location under the BPT 02212 5202 2615 02213 5216 JMP CONT ; then restore the breakpoints and continue PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 59 C Command - Restore Main Memory Context and Continue BTS6120.PLX 2616 .TITLE C Command - Restore Main Memory Context and Continue 2617 2618 2619 ; This routine will restore all the user's registers and return to his 2620 ; program. It is called directly for the continue command, and is used 2621 ; indirectly (to change contexts) by several other commands. 2622 ; 2623 ; When this routine finishes in the most literal sense, the user mode 2624 ; program is running and the monitor is no longer active. However the 2625 ; CONT function can and will actually return, via a POPJ, if the user 2626 ; program causes a breakpoint or single instruction trap. This property is 2627 ; critical to the operation of the Proceed, TRace and Single Instruction 2628 ; commands! 2629 2630 ; Here for the continue command... 2631 02214 6205 CONTCM: .PUSHJ @ZEOLNXT ; continue has no operands 02215 5514 2632 2633 ; If we have a front panel and the HALT switch is currently DOWN, then 2634 ; we want to execute a single instruction only. Only if the HALT switch 2635 ; is UP (or if there's no front panel at all), do we run free! 2636 02216 4777 CONT: JMS @[CHKHLT] ; test the HALT switch 2637 02217 5776 JMP @[TRACE] ; down - trace one instruction instead 2638 ; up - proceed normally 2639 2640 ; Select free running mode and insert all breakpoints... 2641 02220 6205 .PUSHJ @[BPTINS] ; insert all breakpoints 02221 5775 2642 02222 3047 DCA SIMFLG ; clear our software single step flag 2643 02223 6003 PGO ; make sure the HALT flip-flop is cleared 2644 02224 5227 JMP CONT1 ; restore registers and resume 2645 2646 2647 ; The monitor call processor, MCALL, jumps here after it finishes executing 2648 ; a PR0 ROM call. Some of these calls, especially ones that access the disk, 2649 ; take a fairly long time and if the user flips the HALT switch while the 2650 ; program is doing a lot of disk I/O there's a good chance we'll miss it. 2651 ; To fix that, we check the state of the HALT switch after completing a 2652 ; ROM call and just halt if it's been flipped while were busy. 2653 02225 4777 CONT2: JMS @[CHKHLT] ; test the HALT switch 2654 02226 5774 JMP @[HALTED] ; down - pretend we halted after the MUUO 2655 ; otherwise fall into CONT1 and return 2656 2657 2658 ; Restore all registers and context switch. Naturally, part of this involves 2659 ; restoring the original user mode stack pointers, so before we lose our own 2660 ; stack forever, we save a copy of the last monitor stack pointer in RAM. It 2661 ; gets restored by the code at CPSAVE after a breakpoint or single instruction 2662 ; trap. 2663 ; 2664 ; Another gotcha - if a transition on CPREQ L occurs while we're in panel 2665 ; mode, the BTSTRP flag in the panel status will still set anyway. If that 2666 ; happens and we try to continue, the 6120 will trap back to panel mode 2667 ; immediately. The simplest fix for this is to do a dummy read of the panel 2668 ; status flags, which clears them. 2669 02227 6207 CONT1: RSP1 ; get our monitor's stack pointer 2670 02230 3142 DCA STKSAV ; and save it for later 2671 02231 6437 RLON ; turn the RUN LED on 2672 02232 6440 POST+0 ; and show post code 0 2673 02233 6430 CCPR ; make sure no panel request is pending 2674 02234 6000 PRS ; dummy read of panel status to clear BTSTRP 2675 02235 7200 CLA ; ... 2676 02236 1004 TAD USP1 ; reload stack pointer #1 2677 02237 6217 LSP1 ; ... 2678 02240 1005 TAD USP2 ; and stack #2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 60 C Command - Restore Main Memory Context and Continue BTS6120.PLX 2679 02241 6237 LSP2 ; ... 2680 02242 1003 TAD UMQ ; restore the MQ register 2681 02243 7421 MQL ; ... 2682 02244 1002 TAD UFLAGS ; restore the flags, including IF, DF and LINK 2683 02245 6005 RTF ; ... 2684 02246 1001 TAD UAC ; restore the AC 2685 02247 6004 PEX ; exit panel mode 2686 02250 5400 JMP @UPC ; and, lastly, restore the PC 2687 2688 ; At this point we're running the main memory program. If that program 2689 ; causes a breakpoint or single instruction trap, then the HM6120 will enter 2690 ; the CPSAVE routine thru the vector at 7777. After it figures out the reason 2691 ; for the trap, CPSAVE will restore the original monitor's stack, from STKSAV, 2692 ; and execute a .POPJ. Only then will this routine "return". PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 61 ST Command -- Start a Main Memory Program BTS6120.PLX 2693 .TITLE ST Command -- Start a Main Memory Program 2694 2695 2696 ; The start command initializes the CPU registers and all I/O devices and 2697 ; then transfers control to a main memory (user) program. A single, optional, 2698 ; argument may be given to specify the start address of the the main memory 2699 ; program. If the start address is omitted, then the default is location 2700 ; 7777 of field 0 (this is a little strange by PDP-8 standards, but it's the 2701 ; typical reset vector for 6100 and 6120 devices). For example: 2702 ; 2703 ; >ST 00200 - start at location 200 in field 0 (DF is also 0) 2704 ; >ST 70200 - start at location 200 in field 7 (DF is also 7) 2705 ; >ST - start at location 7777 of field 0 (DF is also 0) 2706 ; 2707 02251 6205 START: .PUSHJ @ZGET ; get the next character 02252 5515 2708 02253 7650 SNA CLA ; is there anything out there ?? 2709 02254 5275 JMP START1 ; no -- use the defaults 2710 2711 ; Start at a specific (non-default) address... 2712 02255 6205 .PUSHJ @ZBACKUP ; backup to the start of the address 02256 5512 2713 02257 6205 .PUSHJ @[OCTNI] ; then read it 02260 5773 2714 02261 6205 .PUSHJ @ZEOLTST ; now it has to be the end of the line 02262 5513 2715 02263 6205 .PUSHJ CLRCPU ; clear the saved main memory registers 02264 5312 2716 02265 1065 TAD WORD ; and overwrite the PC with the desired address 2717 02266 3000 DCA UPC ; ... 2718 02267 1036 TAD ADRFLD ; get the start field 2719 02270 7112 CLL RTR ; and make the DF be the same 2720 02271 7106 CLL RTL ; ... 2721 02272 1036 TAD ADRFLD ; ... 2722 02273 3002 DCA UFLAGS ; those are the default processor flags 2723 02274 5216 JMP CONT ; insert any breakpoints and then go 2724 2725 ; Start at the default address. 2726 02275 6205 START1: .PUSHJ CLRCPU ; set all main saved CPU registers to default 02276 5312 2727 02277 5216 JMP CONT ; and then start there PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 62 MR Command - Master Reset BTS6120.PLX 2728 .TITLE MR Command - Master Reset 2729 2730 2731 ; The MR command executes a CAF instruction to assert IOCLR L and initialize 2732 ; all external I/O devices, and then it resets the saved state of the main 2733 ; memory program to the "default" values. From the point of view of an I/O 2734 ; device on the bus, this is equivalent to pressing the RESET button, but it 2735 ; doesn't actually reset the CPU itself (which would re-initialize this 2736 ; monitor!). This command doesn't have any effect on the contents of main 2737 ; memory. 2738 02300 6205 CLRCOM: .PUSHJ @ZEOLNXT ; There are no operands 02301 5514 2739 2740 ; Initialize the saved user context... 2741 02302 6205 .PUSHJ CLRCPU ; clear UAC, UPC, UMQ, etc... 02303 5312 2742 2743 ; Execute a CAF instruction to clear all I/O devices. On the IM6100 we 2744 ; couldn't do this, since CAF would also clear the CP flag (!), but the 6120 2745 ; designers allowed for this case. 2746 ; 2747 ; Unfortunately IOCLR L also resets the console UART, which plays havoc 2748 ; with any character that we might be transmitting at the moment. The only 2749 ; safe thing is to wait for the console to finish before executing the CAF. 2750 ; Note that this will _leave_ the console flag cleared, which is the way a 2751 ; real PDP-8 program should expect it (clearing a real PDP-8 clears the 2752 ; console flag too, after all). 2753 02304 6041 TSF ; has the console finished yet? 2754 02305 5304 JMP .-1 ; no - wait for it 2755 02306 6007 CAF ; clear all I/O flags 2756 2757 ; Reset the IDE disk too. If none is attached, then this is harmless... 2758 ;[250] JMS @ZPUSHJ1 ; (cross field call) 2759 ;[250] IDEINI ; reset the IDE disk and then return 2760 02307 4527 JMS @ZPUSHJ1 ; (cross field call) 2761 02310 1713 INIPMP ; and initialize the partition map 2762 02311 5772 JMP @[EXMEM] ; sync the FP6120 display and we're done 2763 2764 2765 ; This routine is called by the START and RESET commands and at system 2766 ; initialization to clear the saved user context... 2767 02312 7200 CLRCPU: CLA ; start with all zeros 2768 02313 3001 DCA UAC ; clear the AC 2769 02314 3003 DCA UMQ ; and the MQ 2770 02315 3002 DCA UFLAGS ; the DF, IF and LINK 2771 02316 3004 DCA USP1 ; stack pointer #1 2772 02317 3005 DCA USP2 ; and #2 2773 02320 3061 DCA FPPGMM ; clear the front panel program mode 2774 02321 7240 STA ; then finally set the PC to 7777 2775 02322 3000 DCA UPC ; ... 2776 02323 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 63 EX Command - Execute IOT Instructions BTS6120.PLX 2777 .TITLE EX Command - Execute IOT Instructions 2778 2779 2780 ; The EX command allows a user to type in and execute an IOT instruction 2781 ; directly from the terminal, which can be very useful for testing peripheral 2782 ; devices. Either one or two operands are allowed - the first is the octal 2783 ; code of the IOT to be executed, and the second (which is optional) is a 2784 ; value to be placed in the AC before the IOT is executed. If it is omitted, 2785 ; zero is placed in the AC. After the instruction is executed, the word SKIP 2786 ; is typed if the instruction skipped, along with the new contents of the AC. 2787 ; 2788 ; >EX 6471 -> execute IOT 6741 (the AC will be cleared) 2789 ; >EX 6474 1176 -> put 1176 in the AC and execute IOT 6474 2790 ; 2791 ; WARNING - some care must be exercised with this command, since executing 2792 ; the wrong IOT can crash the monitor! 2793 02324 6205 XCTCOM: .PUSHJ @ZOCTNW ; go read the IOT instruction code 02325 5516 2794 02326 1065 TAD WORD ; then get the value 2795 02327 3350 DCA XCTBLK ; save that where we'll execute it 2796 02330 3065 DCA WORD ; assume to use zero in the AC 2797 02331 1050 TAD SAVCHR ; next get the break character 2798 02332 7650 SNA CLA ; was it the end of the line ?? 2799 02333 5340 JMP XCT1 ; yes -- default to zero 2800 02334 6205 .PUSHJ @ZOCTNW ; no -- read another number 02335 5516 2801 02336 6205 .PUSHJ @ZEOLTST ; then test for the end of the line 02337 5513 2802 2803 ; Be sure the instruction is really an IOT... 2804 02340 1350 XCT1: TAD XCTBLK ; get the instruction 2805 02341 1371 TAD [-6000] ; compare it to 6000 2806 02342 7700 SMA CLA ; is it an IOT or OPR instruction ? 2807 02343 5346 JMP XCT2 ; yes -- that's OK 2808 02344 4526 JMS @ZERROR ; no -- don't allow this 2809 02345 3430 ERRILV ; ?ILLEGAL VALUE 2810 2811 ; Execute the instruction... 2812 02346 3067 XCT2: DCA COUNT ; will be non-zero if the IOT doesn't skip 2813 02347 1065 TAD WORD ; get the value we're supposed to put in the AC 2814 02350 7000 XCTBLK: NOP ; gets overwritten with the IOT to execute 2815 02351 2067 ISZ COUNT ; set the flag if it doesn't skip 2816 02352 3044 DCA VALUE ; and remember what is left in the AC 2817 2818 ; Print the results of the instruction.. 2819 02353 1067 TAD COUNT ; see if it skipped 2820 02354 7640 SZA CLA ; well ?? 2821 02355 5360 JMP XCT3 ; no -- no message 2822 02356 4507 JMS @ZINLMES ; yes -- say that it did 2823 02357 3475 SKPMSG ; ... 2824 02360 4507 XCT3: JMS @ZINLMES ; then print the AC after the instruction 2825 02361 3711 ACNAME ; ... 2826 02362 1044 TAD VALUE ; ... 2827 02363 5500 JMP @ZTOCT4C ; in octal, with a CRLF, and return 2828 02371 2000 02372 5751 02373 7000 02374 7711 02375 2077 02376 2146 02377 6031 2829 02400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 64 OS/8 Bootstrap BTS6120.PLX 2830 .TITLE OS/8 Bootstrap 2831 2832 2833 ; How to boot OS/8 (there's lots of documentation on how to write a device 2834 ; handler, even a system handler, but I couldn't find a description of how 2835 ; to make a bootable device anywhere!): 2836 ; 2837 ; The primary bootstrap for a device (the one which you have to toggle in 2838 ; with the switches!) normally loads cylinder 0, head 0, sector 0 (which is 2839 ; the equivalent to OS/8 logical block zero) into memory page zero field zero. 2840 ; The code loaded into page zero is then started in some device specific way, 2841 ; but usually the primary bootstrap is overwritten by this data and the CPU 2842 ; just "ends up" there. 2843 ; 2844 ; The first few words of block zero are called the secondary bootstrap, and 2845 ; it's normally found in the header for the system device handler. OS/8 BUILD 2846 ; copies this code from the handler to block zero when it builds the system 2847 ; device. The second half of block zero contains the system handler, what's 2848 ; resident in page 7600 while OS/8 is running, plus some OS/8 resident code 2849 ; that BUILD wraps around it. All of the second half of block zero must be 2850 ; loaded into page 7600, field 0 by the secondary bootstrap. 2851 ; 2852 ; The remainder of the first half of block zero, the part after the secondary 2853 ; bootstrap, contains the OS/8 resident code for field 1. This starts some 2854 ; where around offset 47 in the first half of block zero, and this code needs 2855 ; to be loaded into the corresponding locations of page 7600, field 1. The 2856 ; remaining words in page 7600, field 1 (i.e. those that belong to the 2857 ; secondary bootstrap) OS/8 uses for tables and their initial values are 2858 ; unimportant. It suffices to simply copy all of the first half of block zero 2859 ; to page 7600, field 1. 2860 ; 2861 ; All this discussion presupposes a single page system handler, as we have 2862 ; here. For a two page handler BUILD will put the second page in the first 2863 ; half of block 66 on the system device and I believe (although I can't 2864 ; guarantee it) that the second half of this block also contains an image 2865 ; of the OS/8 resident code at page 7600, field 1. This would make it the 2866 ; same as, excepting the bootstrap part, the first half of block zero. In 2867 ; the case of a two page handler, the secondary bootstrap is also responsible 2868 ; for loading the second handler page from block 66 into page 7600, field 2. 2869 ; OS/8 bootstrap code (secondary bootstrap). 2870 ; 2871 ; Once everything has been loaded, the secondary bootstrap can simply do a 2872 ; "CDF CIF 0" and then jump to location 7600 to load the keyboard monitor. 2873 ; 2874 ; The primary bootstrap for the SBC6120 RAM and IDE disks are six words 2875 ; loaded in locations 0 thru 5: 2876 ; 2877 ; 0000/ 6206 PR0 / execute a panel request 2878 ; 0001/ 0001 1 / 1 for RAM disk, 4 for IDE disk 2879 ; 0002/ 0100 0100 / read one page into field zero 2880 ; 0003/ 0000 0000 / location zero 2881 ; 0004/ 0000 0000 / from page/block zero of the device 2882 ; 0005/ 7402 HLT / should never get here 2883 ; 2884 ; If all goes well, the HLT in location 5 is never executed - it gets 2885 ; overwritten by the secondary bootstrap code before the ROM returns from 2886 ; the PR0 function. 2887 ; 2888 ; The B (BOOT) command in BTS6120 actually bypasses the primary bootstrap 2889 ; step and simply reads block zero of the boot device into page zero, field 2890 ; zero directly. The VM01 and ID01 secondary bootstraps all contain a special 2891 ; "key" in words 0 thru 4, the ones which would normally overwrite the primary 2892 ; boostrap, and BTS6120 looks for this key to identify a bootable volume. 2893 ; If the key is found, then BTS6120 simply jumps to main memory location 5 2894 ; to start the secondary bootstrap and finish loading OS/8. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 65 OS/8 Bootstrap BTS6120.PLX 2895 ; 2896 ; This system should also work for any other, non OS/8, system provided that 2897 ; it uses the same primary bootstrap shown above and that its secondary boot 2898 ; contains the special key in the first five words. As long as the secondary 2899 ; bootstrap starts at offset 5, the remainder of its code is unimportant to 2900 ; BTS6120 and it can do anything it likes. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 66 Boot Sniffer BTS6120.PLX 2901 .TITLE Boot Sniffer 2902 2903 2904 ; The secondary bootstraps for both VM01 and ID01 devices contain a special 2905 ; key, the ASCIZ string "BOOT", in the first five words. The caller is 2906 ; expected to read block zero of the boot device into memory, and then call 2907 ; this routine to examine page zero, field zero, of main memory to determine 2908 ; if a valid secondary bootstrap exists. If the key is found, then the LINK 2909 ; will be cleared on return... 2910 02400 1377 CKBOOT: TAD [BOOKEY-1] ; point X1 to the key string 2911 02401 3010 DCA X1 ; ... 2912 02402 7240 NL7777 ; and point X2 to page zero of main memory 2913 02403 3011 DCA X2 ; ... 2914 02404 7100 CKBOO1: CLL ; be sure the LINK is in a known state 2915 02405 1410 TAD @X1 ; get the next word of the key 2916 02406 7450 SNA ; have we done them all ? 2917 02407 6225 .POPJ ; yes - return success 2918 02410 7041 CIA ; make it negative 2919 02411 6266 CPD ; address main memory now 2920 02412 1411 TAD @X2 ; and compare our key to what's there 2921 02413 0130 AND ZK177 ; (PAL8 likes to set the high bit for ASCII!) 2922 02414 6276 SPD ; (back to panel memory) 2923 02415 7120 STL ; assume that we failed 2924 02416 7640 SZA CLA ; did the key match ? 2925 02417 6225 .POPJ ; nope - return with the LINK set 2926 02420 5204 JMP CKBOO1 ; yes - keep testing... 2927 2928 ; Ok, here it is - the magic key that makes a volume bootable! 2929 02421 BOOKEY: .ASCIZ /BOOT/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 67 B Command - Boot Disk BTS6120.PLX 2930 .TITLE B Command - Boot Disk 2931 2932 2933 ; The B command boots, or at least it tries to, either RAM or IDE disk. 2934 ; It can be used with an argument to specify the device to be booted, or 2935 ; without to ask BTS6120 to search for a bootable volume. For example: 2936 ; 2937 ; >B VM - boot device VMA0 2938 ; >B ID - boot device IDA0 2939 ; >B - search VMA0, then IDA0, for a bootstrap 2940 ; 2941 ; If no valid bootsrap can be found, then the message "?Not bootable" is 2942 ; printed. 2943 ; 2944 ; NOTE: It is currently only possible to bootstrap from unit zero for RAM 2945 ; disk, or partition zero in the case of IDE disk. 2946 ; 2947 ; NOTE also - the BOOT command ignores the state of the front panel (if 2948 ; any) RUN/HALT switch. In particular, it doesn't single step if the 2949 ; HALT switch is down when this command is executed. That seems like 2950 ; the most sensible thing. 2951 02426 6205 BOOT: .PUSHJ @ZSPACMP ; get the next non-space character 02427 5510 2952 02430 7650 SNA CLA ; is it the end of the line ? 2953 02431 5252 JMP BOOT1 ; yes - go search for a bootstrap 2954 02432 6205 .PUSHJ @ZBACKUP ; nope - backup to the first letter 02433 5512 2955 02434 6205 .PUSHJ @[NAMENW] ; and read the boot device name 02435 5776 2956 02436 6205 .PUSHJ @ZEOLNXT ; now there has to be an EOL 02437 5514 2957 2958 ; Here if a specific device name is given on the command line... 2959 02440 1375 TAD [BNAMES-1] ; point to the table of boot names 2960 02441 6205 .PUSHJ @[MATCH] ; go call the right boot routine 02442 5774 2961 02443 7430 SZL ; did we find a bootstrap ? 2962 02444 5262 JMP NOBOOT ; nope - print an error message 2963 2964 ; Now do the equivalent of a "ST 5" to start the bootstrap running... 2965 02445 6205 BOOTGO: .PUSHJ @[CLRCPU] ; clear all saved main memory state 02446 5773 2966 02447 1372 TAD [5] ; the secondary bootstrap starts at offset 5 2967 02450 3000 DCA UPC ; ... 2968 02451 5771 JMP @[CONT] ; cross your fingers! 2969 2970 ; Here to search for a bootable device... 2971 02452 6205 BOOT1: .PUSHJ BTVMA0 ; first try booting VMA0 02453 5264 2972 02454 7420 SNL ; did we succeed? 2973 02455 5245 JMP BOOTGO ; yes - go start the bootstrap 2974 02456 6205 .PUSHJ BTIDA0 ; nope - try IDA0 next 02457 5300 2975 02460 7420 SNL ; how about this? 2976 02461 5245 JMP BOOTGO ; yes - use that on instead 2977 2978 ; Here if no bootstrap can be found... 2979 02462 4526 NOBOOT: JMS @ZERROR ; print an error and return to command level 2980 02463 3526 ERRNBT ; ?NO BOOTSTRAP 2981 2982 2983 ; Here to attempt booting VMA0... 2984 02464 4527 BTVMA0: JMS @ZPUSHJ1 ; (cross field call) 2985 02465 0400 RDBOOT ; RAM disk primary bootstrap 2986 02466 6205 .PUSHJ CKBOOT ; is this volume bootable? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 68 B Command - Boot Disk BTS6120.PLX 02467 5200 2987 02470 7430 SZL ; skip if yes 2988 02471 6225 .POPJ ; not bootable - just give up 2989 02472 4507 JMS @ZINLMES ; say 2990 02473 4105 VMAMSG ; "-VMA0" 2991 02474 6205 .PUSHJ @ZCRLF ; ... 02475 5506 2992 02476 7100 CLL ; be sure to return success 2993 02477 6225 .POPJ ; ... 2994 2995 2996 ; Here to attempt booting IDA0... 2997 02500 4527 BTIDA0: JMS @ZPUSHJ1 ; (cross field call) 2998 02501 1200 IDBOOT ; IDE disk primary bootstrap 2999 02502 6205 .PUSHJ CKBOOT ; is this volume bootable? 02503 5200 3000 02504 7430 SZL ; skip if yes 3001 02505 6225 .POPJ ; not bootable - just give up 3002 02506 4507 JMS @ZINLMES ; say 3003 02507 4112 IDAMSG ; "-IDA0" 3004 02510 6205 .PUSHJ @ZCRLF ; ... 02511 5506 3005 02512 7100 CLL ; and be sure to return success 3006 02513 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 69 Parse FORMAT Unit/Partition Argument BTS6120.PLX 3007 .TITLE Parse FORMAT Unit/Partition Argument 3008 3009 3010 ; This routine will parse the unit/partition number argument for FORMAT. 3011 ; Since this command is little on the dangerous side (it does erase all the 3012 ; data on the disk, after all!), we'll go to the extraordinary length of 3013 ; asking for confirmation before we do anything. Confirmation is nothing 3014 ; more than a single character (we don't wait for a carriage return) - "Y" 3015 ; continues with the format and anything else, including ^C, aborts... 3016 ; 3017 ; Assuming the user confirms, then the unit/partition number will be 3018 ; returned in the AC. If the user aborts, or if there are any syntax 3019 ; errors, then we restart the command scanner and never return. 3020 02514 6205 FMTARG: .PUSHJ @ZOCTNW ; read the unit/partition number 02515 5516 3021 02516 6205 .PUSHJ @ZEOLTST ; that has to be followed by the end of line 02517 5513 3022 02520 4507 JMS @ZINLMES ; say 3023 02521 3743 FCFMSG ; "Format partition/unit " 3024 02522 1065 TAD WORD ; get the partition number once again 3025 02523 3044 DCA VALUE ; TOCT corrupts WORD, 3026 02524 1044 TAD VALUE ; .... so we have to stash it here 3027 02525 6205 .PUSHJ @ZTOCT4S ; and type it out 02526 5502 3028 02527 6205 .PUSHJ @[CONFRM] ; go wait for a "Y" or "y" 02530 5770 3029 02531 7620 SNL CLA ; did he confirm? 3030 02532 5524 JMP @ZRESTA ; no - just abort now 3031 02533 1044 TAD VALUE ; yes he did - return the unit in the AC 3032 02534 6225 .POPJ ; ... 3033 3034 ; Here if the RAM disk unit number is illegal... 3035 02535 4526 NOUNIT: JMS @ZERROR ; ... 3036 02536 3430 ERRILV ; "?Illegal value" 3037 3038 ; This little routine verifies that a hard disk is attached to the system. 3039 ; If there is none, then an error message is printed and the command aborted. 3040 ; HOOK: an extension ROM can intercept this call in order to do its own 3041 ; checking if a disk is installed, e.g. in the case of a system with 3042 ; a storage device on a different interface. 3043 02537 7000 NODISK: NOP 3044 02540 7000 NOP 3045 02541 7000 NOP 3046 02542 6211 CDF 1 ; there's a disk attached 3047 02543 1767 TAD @[DKSIZE] ; ... only if DKSIZE != 0 3048 02544 6201 CDF 0 ; ... 3049 02545 7640 SZA CLA ; skip if there's no disk there 3050 02546 6225 .POPJ ; yes - return now 3051 02547 4526 JMS @ZERROR ; print a message and abort the command 3052 02550 3537 ERRNDK ; "?No disk" 3053 02567 0022 02570 7025 02571 2216 02572 0005 02573 2312 02574 6642 02575 3373 02576 6600 02577 2420 3054 02600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 70 PM Command - Show and Edit Disk Partition Map BTS6120.PLX 3055 .TITLE PM Command - Show and Edit Disk Partition Map 3056 3057 3058 ; The PM command allows the default mapping of OS/8 units to IDE disk 3059 ; partitions to be changed. PM accepts two arguments, both of which are 3060 ; optional. The first argument is the OS/8 logical unit number, and the 3061 ; second argument a partition number, in octal. Used without any arguments, 3062 ; the PM command will display a list of all eight OS/8 units and their current 3063 ; mappings. With one argument, PM will display only the mapping for that 3064 ; unit, and with two arguments PM will change the mapping of that unit. 3065 ; 3066 ; >PM u pppp - map OS/8 ID01 unit u to IDE partition pppp 3067 ; >PM u - display the mapping for unit u 3068 ; >PM - display the mapping for all units 3069 ; 3070 02600 6205 PMEDIT: .PUSHJ @ZSPACMP ; get the next non-space character 02601 5510 3071 02602 7650 SNA CLA ; is it the end of the line ? 3072 02603 5241 JMP PMALL ; yes - show the entire map 3073 02604 6205 .PUSHJ @ZBACKUP ; nope - backup and read this character 02605 5512 3074 02606 6205 .PUSHJ @ZOCTNW ; it should be a unit number 02607 5516 3075 02610 1065 TAD WORD ; get the value we read 3076 02611 0377 AND [7770] ; and the unit number must be less than 7 3077 02612 7640 SZA CLA ; ?? 3078 02613 5237 JMP PMEDI1 ; nope - "Illegal value" 3079 02614 1065 TAD WORD ; transfer the unit number 3080 02615 3067 DCA COUNT ; to COUNT for later use 3081 3082 ; See if there's also a partition number on the line... 3083 02616 6205 .PUSHJ @ZSPACM0 ; get the next non-space character 02617 5511 3084 02620 7650 SNA CLA ; is it the end of the line? 3085 02621 5252 JMP PMSHOW ; yes - print the mapping for this unit only 3086 02622 6205 .PUSHJ @ZBACKUP ; nope - read what comes next 02623 5512 3087 02624 6205 .PUSHJ @ZOCTNW ; this should be the partition number 02625 5516 3088 02626 6205 .PUSHJ @ZEOLTST ; and then we have to be at the EOL 02627 5513 3089 3090 ; Here to change the mapping for a specific unit... 3091 02630 1067 TAD COUNT ; get the unit number 3092 02631 1376 TAD [PARMAP-1] ; and make an index into the mapping table 3093 02632 3010 DCA X1 ; ... 3094 02633 1065 TAD WORD ; get the desired mapping 3095 02634 3410 DCA @X1 ; and update the partition table 3096 02635 6222 CIF 2 3097 02636 5775 JMP @[WRPSS] ; store the PM in NVRAM if it exists 3098 ; and we're all done 3099 3100 ; Here if the unit number is illegal... 3101 02637 4526 PMEDI1: JMS @ZERROR ; say 3102 02640 3430 ERRILV ; "?Illegal value" and abort 3103 3104 3105 ; Here to show all eight entries in the entire partition map... 3106 02641 3067 PMALL: DCA COUNT ; start with unit zero 3107 02642 6205 .PUSHJ PMSHOW ; and show the mapping for that unit 02643 5252 3108 02644 2067 ISZ COUNT ; now onto the next one 3109 02645 1067 TAD COUNT ; have we done eight ? 3110 02646 1377 TAD [-10] ; ??? 3111 02647 7640 SZA CLA ; well ? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 71 PM Command - Show and Edit Disk Partition Map BTS6120.PLX 3112 02650 5242 JMP PMALL+1 ; nope - keep going 3113 02651 6225 .POPJ ; yes, we can quit now 3114 3115 ; Here to show the mapping for the unit in COUNT... 3116 02652 4507 PMSHOW: JMS @ZINLMES ; say 3117 02653 4065 PM1MSG ; "Unit " 3118 02654 1067 TAD COUNT ; get the selected unit 3119 02655 6205 .PUSHJ @[TDIGIT] ; and type it 02656 5774 3120 02657 4507 JMS @ZINLMES ; now say 3121 02660 4072 PM2MSG ; " mapped to partition " 3122 02661 1067 TAD COUNT ; get the count again 3123 02662 1376 TAD [PARMAP-1] ; and index the partition table 3124 02663 3010 DCA X1 ; ... 3125 02664 1410 TAD @X1 ; get the partition mapped to this unit 3126 02665 5500 JMP @ZTOCT4C ; type it, in octal, and a CRLF PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 72 Disk Formatter, Pass 1 BTS6120.PLX 3127 .TITLE Disk Formatter, Pass 1 3128 3129 3130 ; Pass one of the RAM/IDE disk formatter writes every block with a simple 3131 ; test pattern consisting of alternating words filled with the block number 3132 ; and its complement. Although it's not too creative, this pattern does do 3133 ; two things - it guarantees that each block is unique (so we can make sure 3134 ; the disk addresssing is working!) and it does ensure that every bit gets 3135 ; tested with a zero and a one (so we can make sure the data lines are 3136 ; working). 3137 ; 3138 ; This routine expects that a number of memory locations will be initialized 3139 ; before it's called. RECSIZ must contain the negative of the logical record 3140 ; size for the device (-256 for IDE disk or -128 for RAM disk). FMTCNT should 3141 ; contain the negative of the device size, in blocks/pages, and FMTWRP (a 3142 ; location in this routine!) must be initialized with the address of the 3143 ; disk write routine... 3144 02666 4507 FMTP1: JMS @ZINLMES ; say 3145 02667 3763 FM1MSG ; ... "Writing " 3146 02670 6211 CDF 1 ; ... 3147 02671 3537 DCA @ZDKRBN ; reset the current disk block 3148 02672 3536 DCA @ZRDPAGE ; and page numbers 3149 3150 ; Fill the disk buffer with the test pattern... 3151 02673 1071 FMTP11: TAD RECSIZ ; get the negative of the record size 3152 02674 7130 CLL CML RAR ; and divide it by two 3153 02675 3067 DCA COUNT ; since we'll fill the buffer in word pairs 3154 02676 1373 TAD [DSKBUF-1] ; point X1 to the disk buffer 3155 02677 3010 DCA X1 ; ... 3156 02700 6211 CDF 1 ; (the disk buffer is in field 1) 3157 02701 1073 FMTP12: TAD FMTCNT ; get the current block/page number 3158 02702 3410 DCA @X1 ; store that 3159 02703 1073 TAD FMTCNT ; then store its complement 3160 02704 7040 CMA ; ... 3161 02705 3410 DCA @X1 ; in the next word 3162 02706 2067 ISZ COUNT ; have we done the whole buffer? 3163 02707 5301 JMP FMTP12 ; nope - keep filling 3164 02710 6201 CDF 0 ; return to our default field 3165 3166 ; Write the buffer to the disk... 3167 02711 4527 JMS @ZPUSHJ1 ; (cross field call) 3168 02712 2200 PNLBUF ; setup our temporary buffer in field 1 3169 02713 1071 TAD RECSIZ ; pass the record size to the I/O routine 3170 02714 4527 JMS @ZPUSHJ1 ; (cross field call) 3171 02715 FMTWRP: .BLOCK 1 ; modified to either DISKWR or RAMDWR 3172 02716 7430 SZL ; were there any errors ? 3173 02717 5772 JMP @[DIOERR] ; yes - quit now 3174 3175 ; See if we've done the whole disk... 3176 02720 7200 CLA ; ... 3177 02721 2073 ISZ FMTCNT ; increment the page/block counter 3178 02722 7410 SKP ; not done yet - keep going 3179 02723 6225 .POPJ ; all done! 3180 02724 6211 CDF 1 ; disk data lives in field 1 3181 02725 2537 ISZ @ZDKRBN ; increment the disk block number 3182 02726 2536 ISZ @ZRDPAGE ; and the RAM disk page number 3183 02727 6201 CDF 0 ; back to safe ground 3184 3185 ; Print a dot every so often to make a simple "progress bar"... 3186 02730 1071 TAD RECSIZ ; get the current record size 3187 02731 7040 CMA ; and make it a mask for the lower bits 3188 02732 0073 AND FMTCNT ; apply it to the current block/page number 3189 02733 7640 SZA CLA ; ... 3190 02734 5273 JMP FMTP11 ; not time for a dot yet 3191 02735 6205 .PUSHJ @ZTDOT ; print a dot to show our progress PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 73 Disk Formatter, Pass 1 BTS6120.PLX 02736 5505 3192 02737 5273 JMP FMTP11 ; and another page or block 3193 02772 3504 02773 7377 02774 7102 02775 0243 02776 0017 02777 7770 3194 03000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 74 Disk Formatter, Pass 2 BTS6120.PLX 3195 .TITLE Disk Formatter, Pass 2 3196 3197 3198 ; Pass two of the RAM/IDE disk formatter reads back every block and verifies 3199 ; that the test pattern written by pass 1 is there. If any block doesn't 3200 ; contain the data we expect, then a "Verification error" message will be 3201 ; printed, but verification continues. This routine expects all the same 3202 ; data to be set up in FMTCNT and RECSIZ as Pass 1, and in addition it 3203 ; expects FMTRDP to be initialized with the address of the disk read routine. 3204 03000 4507 FMTP2: JMS @ZINLMES ; say 3205 03001 3772 FM2MSG ; "Verifying" 3206 03002 6211 CDF 1 ; ... 3207 03003 3537 DCA @ZDKRBN ; reset the current disk block 3208 03004 3536 DCA @ZRDPAGE ; and page numbers 3209 03005 6201 CDF 0 ; ... 3210 3211 ; Read the next block/page from the disk... 3212 03006 4527 FMTP21: JMS @ZPUSHJ1 ; (cross field call) 3213 03007 2200 PNLBUF ; setup a temporary disk buffer in panel memory 3214 03010 1071 TAD RECSIZ ; pass the record size to DISKRD 3215 03011 4527 JMS @ZPUSHJ1 ; (cross field call) 3216 03012 FMTRDP: .BLOCK 1 ; gets modified to either DISKRD or RAMDRD! 3217 03013 7430 SZL ; any I/O errors ? 3218 03014 5777 JMP @[DIOERR] ; yes - just give up now 3219 3220 ; Verify that the data in the buffer matches what we wrote... 3221 03015 1071 TAD RECSIZ ; and get the block/page size 3222 03016 7130 CLL CML RAR ; divide it by two 3223 03017 3067 DCA COUNT ; because we'll test in double word pairs 3224 03020 1376 TAD [DSKBUF-1] ; point X1 to the disk buffer 3225 03021 3010 DCA X1 ; ... 3226 03022 6211 CDF 1 ; (disk buffer lives in field 1) 3227 03023 1073 FMTP22: TAD FMTCNT ; get the current block/page number 3228 03024 7041 CIA ; make it negative 3229 03025 1410 TAD @X1 ; and compare to the first word in the buffer 3230 03026 7640 SZA CLA ; it matches, no? 3231 03027 5257 JMP FMTP29 ; no - verify error! 3232 03030 1410 TAD @X1 ; the second word is the complement of the page 3233 03031 1073 TAD FMTCNT ; so that plus this 3234 03032 7001 IAC ; plus 1 should be zero! 3235 03033 7640 SZA CLA ; are we right? 3236 03034 5257 JMP FMTP29 ; no - verify error! 3237 03035 2067 ISZ COUNT ; have we done the whole buffer? 3238 03036 5223 JMP FMTP22 ; nope - keep testing 3239 03037 6201 CDF 0 ; return to our regular field 3240 3241 ; See if we've done the whole disk... 3242 03040 2073 FMTP23: ISZ FMTCNT ; increment the page/block counter 3243 03041 7410 SKP ; not done yet - keep going 3244 03042 6225 .POPJ ; all done! 3245 03043 6211 CDF 1 ; disk data lives in field 1 3246 03044 2537 ISZ @ZDKRBN ; increment the disk block number 3247 03045 2536 ISZ @ZRDPAGE ; and the RAM disk page number 3248 03046 6201 CDF 0 ; back to safe ground 3249 3250 ; Print a dot every so often to make a simple "progress bar"... 3251 03047 1071 TAD RECSIZ ; get the current record size 3252 03050 7040 CMA ; and make it a mask for the lower bits 3253 03051 0073 AND FMTCNT ; apply it to the current block/page number 3254 03052 7640 SZA CLA ; ... 3255 03053 5206 JMP FMTP21 ; not time for a dot yet 3256 03054 6205 .PUSHJ @ZTDOT ; print a dot to show our progress 03055 5505 3257 03056 5206 JMP FMTP21 ; and another page or block 3258 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 75 Disk Formatter, Pass 2 BTS6120.PLX 3259 ; Here if one (or more) words don't match.. 3260 03057 6201 FMTP29: CDF 0 ; restore the usual field 3261 03060 6205 .PUSHJ @ZCRLF ; we're in the middle of a line now 03061 5506 3262 03062 4507 JMS @ZINLMES ; so start a new one and print 3263 03063 4010 ERRDSK ; "?Verification error, block/page " 3264 03064 6211 CDF 1 ; (disk data is in field 1) 3265 03065 1537 TAD @ZDKRBN ; get the current block/page number 3266 03066 6201 CDF 0 ; ... 3267 03067 6205 .PUSHJ @ZTOCT4C ; and type it (in octal) 03070 5500 3268 03071 5240 JMP FMTP23 ; better luck with the next block PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 76 DF Command - Format IDE Disk Partition BTS6120.PLX 3269 .TITLE DF Command - Format IDE Disk Partition 3270 3271 3272 ; The DF command will "format" an IDE disk partition. The name is a misnomer 3273 ; because there's nothing about an IDE disk that needs formatting in the way 3274 ; a floppy does, but this command does write and then read back every single 3275 ; block of the partition which serves the useful function of testing the disk. 3276 ; It works in two passes - the first pass writes every block with a test 3277 ; pattern, and the second pass reads and verifies every block for the correct 3278 ; data. 3279 ; 3280 ; >DF pppp - format disk partition pppp 3281 ; 3282 03072 6205 DFRMAT: .PUSHJ @[NODISK] ; verify that a hard disk is attached 03073 5775 3283 03074 6205 .PUSHJ @[FMTARG] ; get the partition and ask for confirmation 03075 5774 3284 03076 6211 CDF 1 ; the IDE disk data lives in field one 3285 03077 3773 DCA @[DKPART] ; save the partition number 3286 03100 6201 CDF 0 ; ... 3287 03101 1135 TAD ZM256 ; the record size for IDE disk is 256 words 3288 03102 3071 DCA RECSIZ ; ... 3289 3290 ; Do pass 1... 3291 03103 3073 DCA FMTCNT ; an IDE partition always holds 4096 blocks 3292 03104 1372 TAD [DISKWR] ; point to the correct I/O routine 3293 03105 3771 DCA @[FMTWRP] ; and point pass 1 towards that 3294 03106 6205 .PUSHJ @[FMTP1] ; go do pass 1 03107 5770 3295 3296 ; And do pass 2... 3297 03110 3073 DCA FMTCNT ; reset the block count to 4096 3298 03111 1367 TAD [DISKRD] ; and point pass 2 to the disk read routine 3299 03112 3212 DCA FMTRDP ; ... 3300 03113 6205 .PUSHJ FMTP2 ; and away we go! 03114 5200 3301 3302 ; We've tested the entire disk... 3303 03115 4507 FRDONE: JMS @ZINLMES ; let the operator know we're done 3304 03116 4003 FM3MSG ; "Finished" 3305 03117 5506 JMP @ZCRLF ; finish the line and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 77 RF Command - Format a RAM Disk BTS6120.PLX 3306 .TITLE RF Command - Format a RAM Disk 3307 3308 3309 ; The RF command will "format" a RAM disk virtual drive and it's essentially 3310 ; identical to the DF command that formats IDE disks. 3311 ; 3312 ; >RF u - format RAM disk unit u 3313 ; 3314 03120 6205 RFRMAT: .PUSHJ @[FMTARG] ; get the unit and ask for confirmation 03121 5774 3315 03122 6211 CDF 1 ; the RAM disk data lives in field one 3316 03123 3766 DCA @[RDUNIT] ; save the unit 3317 03124 6201 CDF 0 ; ... 3318 03125 4527 JMS @ZPUSHJ1 ; (cross field call) 3319 03126 0712 RAMSEL ; try to select this RAM disk unit 3320 03127 7630 SZL CLA ; was the unit number legal ?? 3321 03130 5765 JMP @[NOUNIT] ; nope - quit while we're ahead! 3322 03131 1134 TAD ZM128 ; the record size for RAM disk is 128 words 3323 03132 3071 DCA RECSIZ ; ... 3324 3325 ; Do pass 1... 3326 03133 6211 CDF 1 ; get the size of this RAM disk unit 3327 03134 1764 TAD @[RAMUSZ] ; which is left here by RAMSEL 3328 03135 3073 DCA FMTCNT ; save it for pass 1 3329 03136 6201 CDF 0 ; ... 3330 03137 1363 TAD [RAMDWR] ; get the correct I/O routine 3331 03140 3771 DCA @[FMTWRP] ; and point pass 1 towards that 3332 03141 6205 .PUSHJ @[FMTP1] ; go do pass 1 03142 5770 3333 3334 ; And do pass 2... 3335 03143 6211 CDF 1 ; get the size of this RAM disk unit 3336 03144 1764 TAD @[RAMUSZ] ; which is left here by RAMSEL 3337 03145 3073 DCA FMTCNT ; save it for pass1 3338 03146 6201 CDF 0 ; ... 3339 03147 1362 TAD [RAMDRD] ; and point pass 2 to the disk read routine 3340 03150 3212 DCA FMTRDP ; ... 3341 03151 6205 .PUSHJ FMTP2 ; and away we go! 03152 5200 3342 3343 ; We've tested the entire disk... 3344 03153 5315 JMP FRDONE ; say "Finished" and we're done! 3345 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 3346 03200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 78 LP Command - Load Binary Paper Tapes from the Console BTS6120.PLX 3347 .TITLE LP Command - Load Binary Paper Tapes from the Console 3348 3349 3350 ; The LP command loads a "paper tape" in standard PDP-8 BIN loader format 3351 ; from the console. If the console is actually an ASR-33 and you actually 3352 ; have a real PDP-8 paper tape, then this will probably even work, but a more 3353 ; likely situation is that you're using a PC with a terminal emulator. In 3354 ; that case the paper tape image can be downloaded from the PC's disk. 3355 ; 3356 ; The loader accepts all standard BIN data frames, including field changes, 3357 ; and correctly calculates and verifies the tape checksum. If the checksum 3358 ; matches then the number of words loaded is printed - otherwise a checksum 3359 ; error message is generated. When initially started, this routine ignores 3360 ; all input until two consectutive leader codes (octal 200) are found - this 3361 ; allows us to ignore any extra ASCII characters from the terminal emulator 3362 ; (such as carriage returns, spaces, etc). 3363 ; 3364 ; Since we're using the real console, the same one that you're typing 3365 ; commands on, for input we have a problem in that we need some way to 3366 ; terminate loading. Control-C won't work since the BIN loader eats all 3367 ; eight bit characters. A hardware reset isn't a good idea, since the POST 3368 ; memory test will erase everything we've loaded. Instead we use a special 3369 ; routine, CONGET, to read characters from the console and this routine has a 3370 ; timeout built in. If we go approximately 5 seconds without any input then 3371 ; the loader is terminated. 3372 03200 6205 CONLOD: .PUSHJ @ZEOLNXT ; this command has no operands 03201 5514 3373 03202 3037 DCA PNLMEM ; files are always lodaded into main memory 3374 3375 ; Look for two consecutive bytes of leader code... 3376 03203 1377 BINLO1: TAD [-2] ; we need two bytes of leader/trailer 3377 03204 3067 DCA COUNT ; ... 3378 03205 6205 BINLO2: .PUSHJ CONGET ; go read a byte of input 03206 5325 3379 03207 1376 TAD [-200] ; is this a leader code ?? 3380 03210 7640 SZA CLA ; ?? 3381 03211 5203 JMP BINLO1 ; no -- keep looking for two 3382 03212 2067 ISZ COUNT ; yes -- is this the second in a row ?? 3383 03213 5205 JMP BINLO2 ; no -- go look for the next one 3384 3385 ; Here after we have 2 bytes of leader -- look for the end of the leader... 3386 03214 6205 BINLO3: .PUSHJ CONGET ; get another byte of data 03215 5325 3387 03216 1376 TAD [-200] ; are we still in the leader ?? 3388 03217 7450 SNA ; ??? 3389 03220 5214 JMP BINLO3 ; yes -- keep looking 3390 03221 1375 TAD [200] ; no -- restore the character 3391 03222 3065 DCA WORD ; and remember it for later 3392 3393 ; Now actually start loading data... 3394 03223 3046 DCA CHKSUM ; start with a zero checksum 3395 03224 1375 TAD [200] ; set the default load address to location 200 3396 03225 3035 DCA ADDR ; ... 3397 03226 3036 DCA ADRFLD ; in field zero 3398 3399 ; Decode the type of the next load record... 3400 03227 7621 BINLO5: CAM ; ... 3401 03230 1065 TAD WORD ; Get the last character we read 3402 03231 0375 AND [200] ; Is this a single byte frame ??? 3403 03232 7640 SZA CLA ; ?? 3404 03233 5301 JMP BINLO7 ; Yes -- this is EOF or a field setting 3405 3406 ; Load a two frame record (either data or an address)... 3407 03234 1065 TAD WORD ; get the first byte back again 3408 03235 3323 DCA BINCH1 ; and remember that PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 79 LP Command - Load Binary Paper Tapes from the Console BTS6120.PLX 3409 03236 6205 .PUSHJ CONGET ; then go read the next byte 03237 5325 3410 03240 3324 DCA BINCH2 ; and save that 3411 03241 1323 TAD BINCH1 ; get the first byte 3412 03242 0374 AND [77] ; trim it to just 6 bits 3413 03243 7002 BSW ; put it in the left half 3414 03244 7421 MQL ; and save it in the MQ for now 3415 03245 1324 TAD BINCH2 ; then get the second character 3416 03246 0374 AND [77] ; trim it to 6 bits too 3417 03247 7501 MQA ; and OR it with the first character 3418 03250 3044 DCA VALUE ; remember what we read 3419 3420 ; Determine what to do with this word... 3421 03251 6205 .PUSHJ CONGET ; look ahead one byte 03252 5325 3422 03253 3065 DCA WORD ; save that character 3423 03254 1065 TAD WORD ; and get it back 3424 03255 1376 TAD [-200] ; is this the end of the tape ?? 3425 03256 7650 SNA CLA ; ?? 3426 03257 5314 JMP BINLO8 ; yes -- we read a checksum word 3427 03260 1046 TAD CHKSUM ; no -- checksum the two characters we read 3428 03261 1323 TAD BINCH1 ; ... 3429 03262 1324 TAD BINCH2 ; ... 3430 03263 3046 DCA CHKSUM ; ... 3431 03264 1323 TAD BINCH1 ; then look at the first character 3432 03265 0373 AND [100] ; is this an address or data frame ?? 3433 03266 7640 SZA CLA ; skip if it's data 3434 03267 5276 JMP BINLO6 ; no -- it is an address 3435 3436 ; Load this word of data into memory... 3437 03270 1044 TAD VALUE ; get the word back 3438 03271 6205 .PUSHJ @ZDANDV ; and write it into memory 03272 5523 3439 03273 2035 ISZ ADDR ; automatically advance the address 3440 03274 7000 NOP ; (and ignore any wrap around) 3441 03275 5227 JMP BINLO5 ; then go process the next frame 3442 3443 ; This word is an address... 3444 03276 1044 BINLO6: TAD VALUE ; get the 12 bits of data 3445 03277 3035 DCA ADDR ; and change to that address 3446 03300 5227 JMP BINLO5 ; then go process the next frame 3447 3448 ; Here of the current frame is a field setting... 3449 03301 1065 BINLO7: TAD WORD ; get the last character back again 3450 03302 0373 AND [100] ; see if it is really a field frame 3451 03303 7650 SNA CLA ; ??? 3452 03304 5314 JMP BINLO8 ; no -- treat it like a trailer code 3453 03305 1065 TAD WORD ; get the field back 3454 03306 0131 AND ZK70 ; we only want these bits 3455 03307 3036 DCA ADRFLD ; and change to the selected field 3456 03310 6205 .PUSHJ CONGET ; Then look ahead one byte 03311 5325 3457 03312 3065 DCA WORD ; ... 3458 03313 5227 JMP BINLO5 ; and go process that frame 3459 3460 ; Here when we find the checksum byte... 3461 03314 1044 BINLO8: TAD VALUE ; get the checksum byte 3462 03315 7041 CIA ; make it negative 3463 03316 1046 TAD CHKSUM ; and add it to our checksum 3464 03317 3046 DCA CHKSUM ; this should leave zero 3465 03320 6205 .PUSHJ @[TCKSUM] ; go type the checksum and return 03321 5772 3466 03322 5203 JMP BINLO1 3467 3468 ; Temporary storage for BIN loader routine... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 80 LP Command - Load Binary Paper Tapes from the Console BTS6120.PLX 3469 03323 BINCH1: .BLOCK 1 ; the first of a two character frame 3470 03324 BINCH2: .BLOCK 1 ; the second of a two character frame PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 81 Paper Tape Console Input Routine BTS6120.PLX 3471 .TITLE Paper Tape Console Input Routine 3472 3473 3474 ; This routine will read a character from the console, waiting if there is 3475 ; none ready right now, and with a timeout if one doesn't arrive soon. It is 3476 ; intended to be used only with the paper tape binary loader routine, and most 3477 ; "textual" input should be done via the INCHRS or INCHWL routines. Since the 3478 ; user cannot type control-C to abort the paper tape loader (data is being read 3479 ; from the console, remember ?) this routine provides a timeout feature to 3480 ; prevent the monitor from becoming 'hung'. If no character is received from 3481 ; the console in approximately 10 seconds, a control-C is simulated by jumping 3482 ; to RESTA. 3483 0310 FTCONT=200. ; approximately 10 seconds with a 4.9152Mhz clock 3484 3485 03325 7200 CONGET: CLA ; ... 3486 03326 1371 TAD [-FTCONT] ; get the console timeout time 3487 03327 3055 DCA IRMA ; and set up a counter 3488 3489 ; Try to read a character... 3490 03330 6031 CONGE1: KSF ; is there a character there ??? 3491 03331 5335 JMP CONGE2 ; no -- check the timer 3492 03332 7200 CLA ; yes -- clear the timer 3493 03333 6036 KRB ; and get the character 3494 03334 6225 .POPJ ; then return that 3495 3496 ; Here to keep the timeout counter. The loop between CONGE1 and CONGE2 3497 ; requires 56 states, or approximately .1835 seconds at 2.5Mhz. This is 3498 ; executed FTCONT times for the overall timeout. 3499 03335 7001 CONGE2: IAC ; increment the timer 3500 03336 7440 SZA ; has it counted to 4096 ??? 3501 03337 5330 JMP CONGE1 ; no -- keep waiting 3502 03340 2055 ISZ IRMA ; yes -- have we waited long enough ?? 3503 03341 5330 JMP CONGE1 ; no -- wait a little longer 3504 03342 7325 NL0003 ; yes -- simulate a control-C 3505 03343 6205 .PUSHJ @ZOUTCHR ; echo ^C 03344 5474 3506 03345 5524 JMP @ZRESTA ; and restart 3507 03371 7470 03372 1472 03373 0100 03374 0077 03375 0200 03376 7600 03377 7776 3508 03400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 82 RD and DD Commands - Dump Disk (RAM and IDE) Records BTS6120.PLX 3509 .TITLE RD and DD Commands - Dump Disk (RAM and IDE) Records 3510 3511 3512 ; These commands dump one or more disk records, in octal, to the console. 3513 ; What you get from DP is exactly how the OS/8 device driver sees the disk 3514 ; data. Each command accepts one, two or three parameters. The first is unit 3515 ; number for RAM Disk (RD) commands, or the partition number for IDE Disk (DD) 3516 ; commands. The second parameter is the number of the block to be dumped, in 3517 ; octal. If this number is omitted then the ENTIRE disk will be dumped which, 3518 ; although legal, will take quite a while! The third parameter is the count 3519 ; of pages (for RAM Disk) or blocks (for IDE disk) to be dumped and, if 3520 ; omitted, this defaults to 1. For example: 3521 ; 3522 ; >RD 0 0 - dump only page 0 (the boot block) of RAM disk unit 0 3523 ; >DD 2 100 - dump only page 100 (octal) of IDE partition 2 3524 ; >RD 1 100 77 - dump 64 (77 octal) pages of unit 1 from 100 to 177 3525 ; >DD 0 - dump ALL of IDE partition zero (4095 blocks!) 3526 ; 3527 3528 ; Enter here for the RD command... 3529 03400 1377 RDDUMP: TAD [RAMDRD] ; point to the RAM disk read routine 3530 03401 3267 DCA RDPTR ; modify the code to use that 3531 03402 1134 TAD ZM128 ; get the record size for RAM disk 3532 03403 3071 DCA RECSIZ ; and save that 3533 03404 5213 JMP PARSDX ; fall into the regular code now 3534 3535 ; And here for the DD command... 3536 03405 6205 DDDUMP: .PUSHJ @[NODISK] ; verify that a hard disk exists 03406 5776 3537 03407 1375 TAD [DISKRD] ; point to the IDE disk read routine 3538 03410 3267 DCA RDPTR ; and use that instead 3539 03411 1135 TAD ZM256 ; IDE disk uses 256 word records 3540 03412 3071 DCA RECSIZ ; ... 3541 3542 ; Parse the argument lists for either command... 3543 03413 6205 PARSDX: .PUSHJ @ZOCTNW ; read the unit/partition number (required) 03414 5516 3544 03415 6211 CDF 1 ; all disk data lives in field 1 3545 03416 1065 TAD WORD ; get what we found 3546 03417 3774 DCA @[DKPART] ; save both the partition number 3547 03420 1065 TAD WORD ; ... 3548 03421 3773 DCA @[RDUNIT] ; and the unit number 3549 03422 3537 DCA @ZDKRBN ; set the default starting block/page to zero 3550 03423 3536 DCA @ZRDPAGE ; ... 3551 03424 6201 CDF 0 ; back to the current field 3552 03425 3072 DCA RECCNT ; make the default record count the whole disk 3553 3554 ; See if there's a starting page number on the command line... 3555 03426 6205 .PUSHJ @ZSPACM0 ; are there any more characters in the command? 03427 5511 3556 03430 7650 SNA CLA ; skip if there are 3557 03431 5263 JMP DDUMP1 ; nope - start dumping now 3558 03432 6205 .PUSHJ @ZBACKUP ; yes - re-read the character 03433 5512 3559 03434 6205 .PUSHJ @ZOCTNW ; and read the page/block number 03435 5516 3560 03436 6211 CDF 1 ; back to field 1 3561 03437 1065 TAD WORD ; get the starting block/page number 3562 03440 3537 DCA @ZDKRBN ; and save it for both RAM disk and IDE disk 3563 03441 1065 TAD WORD ; ... 3564 03442 3536 DCA @ZRDPAGE ; ... 3565 03443 6201 CDF 0 ; back to our field 3566 03444 7240 NLM1 ; now the default record count is one 3567 03445 3072 DCA RECCNT ; ... 3568 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 83 RD and DD Commands - Dump Disk (RAM and IDE) Records BTS6120.PLX 3569 ; See if there's a page/block count too.. 3570 03446 6205 .PUSHJ @ZSPACM0 ; still more characters? 03447 5511 3571 03450 7650 SNA CLA ; skip if there are 3572 03451 5263 JMP DDUMP1 ; nope - start dumping now 3573 03452 6205 .PUSHJ @ZBACKUP ; yes - re-read the character 03453 5512 3574 03454 6205 .PUSHJ @ZOCTNW ; and read the page count 03455 5516 3575 03456 1065 TAD WORD ; ... 3576 03457 7041 CIA ; make it negative for ISZ 3577 03460 3072 DCA RECCNT ; and save the count 3578 03461 6205 .PUSHJ @ZEOLTST ; finally, this has to be the end of the line 03462 5513 3579 3580 ; Read a page from the disk into the panel memory buffer and dump it... 3581 03463 4527 DDUMP1: JMS @ZPUSHJ1 ; (call field 1 routine) 3582 03464 2200 PNLBUF ; set the disk buffer to DSKBUF 3583 03465 1071 TAD RECSIZ ; pass the record size to the I/O routine 3584 03466 4527 JMS @ZPUSHJ1 ; (cross field call) 3585 03467 RDPTR: .BLOCK 1 ; gets overwritten with DISKRD or RAMDRD! 3586 03470 7430 SZL ; were there any errors detected ? 3587 03471 5304 JMP DIOERR ; yes - report it and quit 3588 03472 1071 TAD RECSIZ ; nope - get the size of this record 3589 03473 6205 .PUSHJ @[DDBUF] ; and go dump the DSKBUF 03474 5772 3590 03475 6211 CDF 1 ; disk data lives in field 1 3591 03476 2537 ISZ @ZDKRBN ; increment both the IDE block 3592 03477 2536 ISZ @ZRDPAGE ; and RAM disk page 3593 03500 6201 CDF 0 ; ... 3594 03501 2072 ISZ RECCNT ; have we done all we need to? 3595 03502 5263 JMP DDUMP1 ; nope - go dump another one 3596 03503 6225 .POPJ ; yes - we're done (finally!!) 3597 3598 ; Here if a disk I/O error occurs... 3599 03504 6201 DIOERR: CDF 0 ; just in case 3600 03505 3044 DCA VALUE ; save the error code for a minute 3601 03506 4507 JMS @ZINLMES ; say 3602 03507 3502 ERRDIO ; "?I/O Error " 3603 03510 1044 TAD VALUE ; get the error status 3604 03511 6205 .PUSHJ @ZTOCT4M ; type it and a CRLF 03512 5501 3605 ; and abort this command completely PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 84 RL and DL Commands - Load Disk (RAM and IDE) Records BTS6120.PLX 3606 .TITLE RL and DL Commands - Load Disk (RAM and IDE) Records 3607 3608 3609 ; The DL and RL commands allow a disk to be downloaded over the console 3610 ; serial port. The format of the data expected is identical that that 3611 ; generated by the RD and DD (dump RAM/IDE disk) commands, which makes it 3612 ; possible to upload a disk image to the PC and then later download the same 3613 ; image back to the SBC6120. Since all the data is simple printing ASCII 3614 ; text, any terminal emulator program can be used to capture and replay the 3615 ; data will suffice. 3616 ; 3617 ; >RL u - download data to RAM disk unit u 3618 ; >DL pppp - download data to IDE disk partition pppp 3619 ; >FL - download data to Flash ROM 3620 3621 ; Enter here for the RL command... 3622 03513 1371 RLLOAD: TAD [RAMDWR] ; point to the RAM disk write routine 3623 03514 3354 DCA WRPTR ; modify the code to use that 3624 03515 1134 TAD ZM128 ; set the record (page) size for RAM disk 3625 03516 3071 DCA RECSIZ ; ... 3626 03517 5326 JMP DLOAD ; fall into the regular code 3627 3628 ; Enter here for the DL command... 3629 03520 6205 DLLOAD: .PUSHJ @[NODISK] ; verify that a hard disk is attached 03521 5776 3630 03522 1370 TAD [DISKWR] ; this time use the IDE disk write routine 3631 03523 3354 DCA WRPTR ; ... 3632 03524 1135 TAD ZM256 ; and the record (block) size is 256 3633 03525 3071 DCA RECSIZ ; ... 3634 3635 ; Parse the argument for the DL and RL commands... 3636 03526 6205 DLOAD: .PUSHJ @ZOCTNW ; read the unit/partition number (required) 03527 5516 3637 03530 6205 .PUSHJ @ZEOLTST ; that has to be followed by the end of line 03531 5513 3638 03532 6211 CDF 1 ; all disk data lives in field 1 3639 03533 1065 TAD WORD ; get the number entered 3640 03534 3773 DCA @[RDUNIT] ; and set the RAM disk unit number 3641 03535 1065 TAD WORD ; ... 3642 03536 3774 DCA @[DKPART] ; and the IDE disk partition number 3643 03537 6201 CDF 0 ; back to our field now 3644 3645 ; Here to read another disk page of data from the host... 3646 03540 1071 DLOAD1: TAD RECSIZ ; pass the block size in the AC 3647 03541 6205 .PUSHJ @[LDBUF] ; load the disk buffer from the serial port 03542 5767 3648 03543 6211 CDF 1 ; (disk data lives in field 1) 3649 03544 3537 DCA @ZDKRBN ; save the address of the block we read 3650 03545 1537 TAD @ZDKRBN ; ... 3651 03546 3536 DCA @ZRDPAGE ; and the page number too 3652 03547 6201 CDF 0 ; (back to our field now) 3653 03550 4527 JMS @ZPUSHJ1 ; (call field 1 routine) 3654 03551 2200 PNLBUF ; set the disk buffer to DSKBUF 3655 03552 1071 TAD RECSIZ ; pass the record size to the I/O routine 3656 03553 4527 JMS @ZPUSHJ1 ; (call a field 1 routine) 3657 03554 WRPTR: .BLOCK 1 ; gets modified to DISKWR, RAMDWR or ROMWR 3658 03555 7430 SZL ; were there any I/O errors? 3659 03556 5304 JMP DIOERR ; yes - go report that and quit 3660 03557 5340 JMP DLOAD1 ; go read another page 3661 03567 3653 03570 1244 03571 0420 03572 3600 03573 0024 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 85 RL and DL Commands - Load Disk (RAM and IDE) Records BTS6120.PLX 03574 0020 03575 1214 03576 2537 03577 0407 3662 03600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 86 Dump Disk Buffer on Console BTS6120.PLX 3663 .TITLE Dump Disk Buffer on Console 3664 3665 3666 ; This routine will dump the contents of DSKBUF on the console in ASCII. 3667 ; For each block dumped the output format consists of 33 lines of data, where 3668 ; the first 32 lines contain a disk address in the format "." 3669 ; (e.g. "0122.0160" is word 160 (octal) of block 122 (octal)) followed by 8 3670 ; words of data, also in octal. The 33rd line contains just a single octal 3671 ; number, a checksum of all 256 words in the block. 3672 ; 3673 ; This format is exactly the same input that's accepted by the LDBUF, which 3674 ; allows you to capture the output of a disk dump on a PC terminal emulator 3675 ; and then download the same data later to a different disk. This is the 3676 ; primary motivation for the checksum - it isn't too useful to humans, but 3677 ; it will guard against errors in the upload/download procedure. 3678 ; 3679 ; This routine should be called with the number of words to dump in the 3680 ; AC, which will normally be either -256 (to dump an IDE block) or -128 3681 ; (for a RAM disk page). 3682 03600 3252 DDBUF: DCA DDCNT ; save the count of words to dump 3683 03601 3067 DCA COUNT ; and clear the current word count 3684 03602 1377 TAD [DSKBUF-1] ; set up X1 to point to the buffer 3685 03603 3010 DCA X1 ; ... 3686 03604 3046 DCA CHKSUM ; and clear the checksum 3687 3688 ; Start a new line of data... 3689 03605 6211 DDBUF2: CDF 1 ; ... 3690 03606 1537 TAD @ZDKRBN ; get the page/block number we're dumping 3691 03607 6201 CDF 0 ; ... 3692 03610 6205 .PUSHJ @ZTOCT4 ; type it in octal 03611 5477 3693 03612 6205 .PUSHJ @ZTDOT ; then type the separator 03613 5505 3694 03614 1067 TAD COUNT ; then type the offset 3695 03615 6205 .PUSHJ @ZTOCT3 ; ... 03616 5503 3696 03617 6205 .PUSHJ @[TSLASH] ; another separator character 03620 5776 3697 03621 6205 .PUSHJ @ZTSPACE ; ... 03622 5475 3698 3699 ; Dump eight words of data, in octal... 3700 03623 6211 DDBUF3: CDF 1 ; the disk buffer is in field 1 3701 03624 1410 TAD @X1 ; get another word 3702 03625 6201 CDF 0 ; and go back to our field 3703 03626 3044 DCA VALUE ; save it for a minute 3704 03627 1044 TAD VALUE ; get it back 3705 03630 1046 TAD CHKSUM ; and accumulate a checksum 3706 03631 3046 DCA CHKSUM ; ... 3707 03632 1044 TAD VALUE ; now we're ready to type the data 3708 03633 6205 .PUSHJ @ZTOCT4S ; in octal, with a space 03634 5502 3709 03635 2067 ISZ COUNT ; count the number we've done 3710 03636 1067 TAD COUNT ; ... 3711 03637 0132 AND ZK7 ; have we done a complete row of eight? 3712 03640 7640 SZA CLA ; ??? 3713 03641 5223 JMP DDBUF3 ; no - keep going 3714 3715 ; Here after we've finished a line of eight data words... 3716 03642 6205 .PUSHJ @ZCRLF ; start a new line 03643 5506 3717 03644 1067 TAD COUNT ; see if we've done the whole page/block 3718 03645 1252 TAD DDCNT ; compare to the block size 3719 03646 7640 SZA CLA ; ??? 3720 03647 5205 JMP DDBUF2 ; not there yet - keep dumping PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 87 Dump Disk Buffer on Console BTS6120.PLX 3721 03650 1046 TAD CHKSUM ; type just the checksum 3722 03651 5500 JMP @ZTOCT4C ; in octal, with a CRLF, and we're done 3723 3724 3725 ; Local storage for DDBUF... 3726 03652 DDCNT: .BLOCK 1 ; the number of words in this buffer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 88 Load Disk Buffer from Console BTS6120.PLX 3727 .TITLE Load Disk Buffer from Console 3728 3729 3730 ; This routine loads the disk buffer with data from a disk block image 3731 ; transmitted over the console port. The format of the data expected is 3732 ; identical that that generated by the DDBUF routine, which makes it possible 3733 ; to upload a disk image to the PC and then later download the same image back 3734 ; to the SBC6120 with DL. Since all the data is simple printing ASCII text, 3735 ; any terminal emulator program can be used to capture and replay the data. 3736 ; 3737 ; LDBUF prompts for each line of data with a ":", and most terminal emulator 3738 ; programs for the PC can be set to look for this prompting character before 3739 ; transmitting the next line. This eliminates the need to insert fixed delays 3740 ; to avoid overrunning the SBC6120. Since LDBUF reads only printing ASCII 3741 ; characters, a download can be aborted at any time just by typing a control-C 3742 ; and there's no need for a timeout the way there is with loading paper tape 3743 ; images. 3744 ; 3745 ; The expected block size, either -128. for RAM disk or -256. for IDE disk, 3746 ; should be passed in the AC. The data read is left in DSKBUF, and the 3747 ; page/block number, extracted from the data, is left in LDPAGE. Note that 3748 ; in the event a checksum or syntax error is found, LDBUF prints an error 3749 ; message and restarts the command scanner. In that case control never 3750 ; returns to the caller! 3751 03653 3252 LDBUF: DCA DDCNT ; save the expected block size 3752 03654 1377 TAD [DSKBUF-1] ; initialize X1 to point at our buffer 3753 03655 3010 DCA X1 ; ... 3754 03656 3067 DCA COUNT ; count the data words read here 3755 03657 7240 STA ; the current disk page is unknown 3756 03660 3370 DCA LDPAGE ; ... 3757 03661 3046 DCA CHKSUM ; clear the checksum accumulator 3758 3759 ; Read the next line of data... 3760 03662 1375 LDBUF2: TAD [":"] ; prompt for data with a ":" 3761 03663 6205 .PUSHJ @[INCHWL] ; initialize the line input routine 03664 5774 3762 03665 6205 LDBU20: .PUSHJ @[INCHW1] ; read another character into the buffer 03666 5773 3763 03667 7650 SNA CLA ; EOL? 3764 03670 5265 JMP LDBU20 ; nope - keep reading 3765 03671 1067 TAD COUNT ; see how many words we've read so far 3766 03672 1252 TAD DDCNT ; is it time for the checksum? 3767 03673 7650 SNA CLA ; ??? 3768 03674 5352 JMP LDBUF5 ; yes - go parse a checksum record 3769 3770 ; First parse the disk page number and offset. The offset has to match the 3771 ; number of words we've already read, but the disk address is slightly more 3772 ; complicated. For the first data record in a page we allow the address to 3773 ; be anything, and that tells us which disk page is to be written. Each data 3774 ; record after that up to the end of the page has to have the same disk 3775 ; address as the first one. This allows disk pages to be loaded in any random 3776 ; order and, more importantly, it allows unused pages to be skipped. 3777 03675 6205 .PUSHJ @ZOCTNW ; go read an octal number 03676 5516 3778 03677 1065 TAD WORD ; get the value we scanned 3779 03700 7041 CIA ; compare it to LDPAGE 3780 03701 1370 TAD LDPAGE ; ??? 3781 03702 7650 SNA CLA ; do they match ? 3782 03703 5310 JMP LDBUF3 ; yes - all is well 3783 03704 2370 ISZ LDPAGE ; no - is this the first data record? 3784 03705 5525 JMP @ZCOMERR ; not that either - the data is corrupt 3785 03706 1065 TAD WORD ; yes - just use this page number without 3786 03707 3370 DCA LDPAGE ; ... question 3787 03710 1050 LDBUF3: TAD SAVCHR ; get the separator character 3788 03711 1372 TAD [-"."] ; it has to be a "." PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 89 Load Disk Buffer from Console BTS6120.PLX 3789 03712 7640 SZA CLA ; ??? 3790 03713 5525 JMP @ZCOMERR ; nope - bad load format 3791 03714 6205 .PUSHJ @ZOCTNW ; now read the relative offset within the page 03715 5516 3792 03716 1065 TAD WORD ; ... 3793 03717 7041 CIA ; it has to match our data count 3794 03720 1067 TAD COUNT ; does it? 3795 03721 7640 SZA CLA ; ??? 3796 03722 5525 JMP @ZCOMERR ; nope - more bad data 3797 03723 1050 TAD SAVCHR ; one last test 3798 03724 1371 TAD [-"/"] ; the separator this time has to be a slash 3799 03725 7640 SZA CLA ; ??? 3800 03726 5525 JMP @ZCOMERR ; another corrupted data record 3801 3802 ; Now read the rest of the data record, which should consist of exactly 3803 ; eight data words, in octal... 3804 03727 6205 LDBUF4: .PUSHJ @ZOCTNW ; scan the next data word 03730 5516 3805 03731 1065 TAD WORD ; get the value we read 3806 03732 6211 CDF 1 ; remember that the disk buffer is in field 1 3807 03733 3410 DCA @X1 ; and store the data word 3808 03734 1065 TAD WORD ; accumulate a checksum of the data words 3809 03735 1046 TAD CHKSUM ; ... we read 3810 03736 3046 DCA CHKSUM ; ... 3811 03737 6201 CDF 0 ; back to home ground 3812 03740 2067 ISZ COUNT ; count the number of words we've read 3813 03741 1067 TAD COUNT ; let's have a look at it 3814 03742 0132 AND ZK7 ; have we read exactly eight words? 3815 03743 7640 SZA CLA ; skip if we have 3816 03744 5327 JMP LDBUF4 ; no - go read another data word 3817 03745 6205 .PUSHJ @ZGET ; yes - after eight data words 03746 5515 3818 03747 7640 SZA CLA ; ... the next thing should be the EOL 3819 03750 5525 JMP @ZCOMERR ; not EOL - this data is corrupted somehow 3820 03751 5262 JMP LDBUF2 ; this is the EOL - go read another record 3821 3822 ; We get here when we're read 128 or 256 words of data - the next thing we 3823 ; expect to find is a checksum record, which is a single octal number all by 3824 ; itself. This has to match the checksum we've calculated or the data is 3825 ; corrupted. 3826 03752 6205 LDBUF5: .PUSHJ @ZOCTNW ; scan an octal value 03753 5516 3827 03754 1065 TAD WORD ; and get what we found 3828 03755 7041 CIA ; ... 3829 03756 1046 TAD CHKSUM ; compare it to the checksum we accumulated 3830 03757 7640 SZA CLA ; they have to be the same! 3831 03760 5366 JMP DERCKS ; they aren't - bad checksum for data 3832 03761 1050 TAD SAVCHR ; get the next character 3833 03762 7640 SZA CLA ; it has to be the EOL 3834 03763 5525 JMP @ZCOMERR ; no - the syntax of this record is wrong 3835 3836 ; The checksum matches - all is well! 3837 03764 1370 TAD LDPAGE ; return the page number in the AC 3838 03765 6225 .POPJ ; ... 3839 3840 ; Here if the data checksum doesn't match... 3841 03766 4526 DERCKS: JMS @ZERROR ; print a message and restart 3842 03767 3513 ERRCKS ; ?DATA CHECKSUM MISMATCH 3843 3844 ; Local storage for LDBUF... 3845 03770 LDPAGE: .BLOCK 1 ; page number being read 3846 03771 7721 03772 7722 03773 7210 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 90 Load Disk Buffer from Console BTS6120.PLX 03774 7200 03775 0072 03776 7074 03777 7377 3847 04000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 91 PC Command - Copy an IDE Disk Partition BTS6120.PLX 3848 .TITLE PC Command - Copy an IDE Disk Partition 3849 3850 3851 ; The PC command will copy an entire disk partition to another partition. 3852 ; It's a convenient way to create backups of OS/8 partitions, especially since 3853 ; most modern IDE drives have room for thousands of OS/8 partitions! 3854 ; 3855 ; The PE command will compare two partitions, especially useful after a PC. 3856 ; Due to lack of space for another disk buffer the comparison is done by 3857 ; generating a checksum, unfortunately. 3858 ; 3859 ; >PC ssss dddd - copy IDE partition ssss to partition dddd 3860 ; >PE ssss dddd - compare IDE partition ssss to partition dddd 3861 ; 3862 3863 ; common function to get params 3864 04000 6205 GETPP: .PUSHJ @ZOCTNW ; read the source partition number 04001 5516 3865 04002 1065 TAD WORD ; ... 3866 04003 3040 DCA CPYSRC ; ... 3867 04004 6205 .PUSHJ @[SPATST] ; the next character has to be a space 04005 5777 3868 04006 6205 .PUSHJ @ZOCTNW ; then read the destination partition 04007 5516 3869 04010 1065 TAD WORD ; ... 3870 04011 3041 DCA CPYDST ; ... 3871 04012 5513 JMP @ZEOLTST ; that'd better be all there is 3872 3873 04013 6205 PCOMP: .PUSHJ GETPP 04014 5200 3874 04015 4507 JMS @ZINLMES ; say 3875 04016 3772 CE1MSG ; ... "Verifying " 3876 04017 1376 TAD [PCOPYE] ; operation will be compare block 3877 04020 3035 DCA ADDR ; 3878 04021 5241 JMP PCOPY0 3879 3880 04022 6205 PCOPY: .PUSHJ GETPP 04023 5200 3881 3882 ; Ask for confirmation before overwriting the destination partition... 3883 04024 4507 JMS @ZINLMES ; say 3884 04025 4037 CCFMSG ; "Overwrite partition/unit " 3885 04026 1041 TAD CPYDST ; and then type the partition number 3886 04027 6205 .PUSHJ @ZTOCT4S ; ... 04030 5502 3887 04031 6205 .PUSHJ @[CONFRM] ; then wait for a "Y" or "N" 04032 5775 3888 04033 7620 SNL CLA ; did he answer yes??? 3889 04034 5524 JMP @ZRESTA ; nope - just quit now 3890 3891 ; Prepare to begin copying... 3892 04035 4507 JMS @ZINLMES ; say 3893 04036 4056 CP1MSG ; ... "Copying " 3894 04037 1374 TAD [PCOPYW] ; operation will be write block 3895 04040 3035 DCA ADDR ; 3896 3897 04041 6211 PCOPY0: CDF 1 ; reset the current block number 3898 04042 3537 DCA @ZDKRBN ; ... 3899 04043 6201 CDF 0 ; ... 3900 3901 ; Read the next block from the SRC partition... 3902 04044 4527 PCOPY1: JMS @ZPUSHJ1 ; (cross field call) 3903 04045 2200 PNLBUF ; setup a temporary disk buffer in panel memory 3904 04046 1040 TAD CPYSRC ; get the source partition 3905 04047 6211 CDF 1 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 92 PC Command - Copy an IDE Disk Partition BTS6120.PLX 3906 04050 3773 DCA @[DKPART] ; and point DISKRD there 3907 04051 6201 CDF 0 ; ... 3908 04052 1135 TAD ZM256 ; the IDE record size is always 256 words 3909 04053 4527 JMS @ZPUSHJ1 ; (cross field call) 3910 04054 1214 DISKRD ; and go read a block from the disk 3911 04055 7430 SZL ; disk error ?? 3912 04056 5772 JMP @[DIOERR] ; yes - go report it and give up 3913 3914 04057 6205 .PUSHJ @ADDR ; call the operation 04060 5435 3915 3916 ; Print a dot every so often to make a simple "progress bar"... 3917 04061 6211 PCOPY3: CDF 1 ; ... 3918 04062 2771 ISZ @[DKRBN] ; increment the block number 3919 04063 7410 SKP ; still more to go 3920 04064 5276 JMP PCOPY4 ; we've done all 4096 blocks! 3921 04065 1135 TAD ZM256 ; the format command uses the record size as 3922 04066 7040 CMA ; a mask for printing the progress bar 3923 04067 0771 AND @[DKRBN] ; and so we will too 3924 04070 6201 CDF 0 ; ... 3925 04071 7640 SZA CLA ; time for another dot?? 3926 04072 5244 JMP PCOPY1 ; nope - just keep copying 3927 04073 6205 .PUSHJ @ZTDOT ; print a dot to show our progress 04074 5505 3928 04075 5244 JMP PCOPY1 ; and another page or block 3929 3930 ; All done... 3931 04076 6201 PCOPY4: CDF 0 ; ... 3932 04077 4507 JMS @ZINLMES ; say 3933 04100 4003 CP2MSG ; " Done" 3934 04101 5506 JMP @ZCRLF ; and that's all! 3935 3936 ; Operation: write it to the destination... 3937 04102 4527 PCOPYW: JMS @ZPUSHJ1 ; (cross field call) 3938 04103 2200 PNLBUF ; setup the panel memory disk buffer 3939 04104 1041 TAD CPYDST ; change DKPART to the destination partition 3940 04105 6211 CDF 1 ; ... 3941 04106 3773 DCA @[DKPART] ; ... 3942 04107 6201 CDF 0 ; ... 3943 04110 1135 TAD ZM256 ; load the record size for DISKWR 3944 04111 4527 JMS @ZPUSHJ1 ; (cross field call) 3945 04112 1244 DISKWR ; and go write a block to the disk 3946 04113 7430 SZL ; any disk errors? 3947 04114 5772 JMP @[DIOERR] ; yes - give up 3948 04115 6225 .POPJ 3949 3950 ; Operation: compare it to the other partition 3951 ; (1) checksum the disk buffer 3952 04116 6205 PCOPYE: .PUSHJ DBCHKS 04117 5353 3953 04120 3046 DCA CHKSUM 3954 ; (2) read the other partition's block 3955 04121 4527 JMS @ZPUSHJ1 ; (cross field call) 3956 04122 2200 PNLBUF ; setup the panel memory disk buffer 3957 04123 1041 TAD CPYDST ; change DKPART to the destination partition 3958 04124 6211 CDF 1 ; ... 3959 04125 3773 DCA @[DKPART] ; ... 3960 04126 6201 CDF 0 ; ... 3961 04127 1135 TAD ZM256 ; load the record size for DISKWR 3962 04130 4527 JMS @ZPUSHJ1 ; (cross field call) 3963 04131 1214 DISKRD ; and go read a block from the disk 3964 04132 7430 SZL ; any disk errors? 3965 04133 5772 JMP @[DIOERR] ; yes - give up 3966 ; (3) checksum that block 3967 04134 6205 .PUSHJ DBCHKS PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 93 PC Command - Copy an IDE Disk Partition BTS6120.PLX 04135 5353 3968 ; (4) make sure they're equal 3969 04136 7041 CIA 3970 04137 1046 TAD CHKSUM 3971 04140 7450 SNA 3972 04141 6225 .POPJ ; alles ganz gut 3973 ; (5) if they weren't equal, report that 3974 04142 6205 .PUSHJ @ZCRLF ; we're in the middle of a line now 04143 5506 3975 04144 4507 JMS @ZINLMES ; so start a new one and print 3976 04145 4010 ERRDSK ; "?Verification error, block/page " 3977 04146 6211 CDF 1 ; (disk data is in field 1) 3978 04147 1537 TAD @ZDKRBN ; get the current block/page number 3979 04150 6201 CDF 0 ; ... 3980 04151 6205 .PUSHJ @ZTOCT4C ; and type it (in octal) 04152 5500 3981 3982 04153 1370 DBCHKS: TAD [DSKBUF-1] ; point to the disk buffer 3983 04154 3010 DCA X1 3984 04155 1367 TAD [-256.] ; and it's 256 words long 3985 04156 3067 DCA COUNT 3986 04157 6211 CDF 1 3987 04160 1410 PCCHK1: TAD @X1 3988 04161 2067 ISZ COUNT 3989 04162 5360 JMP PCCHK1 3990 04163 6201 CDF 0 3991 04164 6225 .POPJ 3992 04167 7400 04170 7377 04171 0021 04172 3504 04173 0020 04174 4102 04175 7025 04176 4116 04177 6123 3993 04200 .PAGE 3994 .TITLE Initialize Terminal, Breakpoint, Partition Map, etc 3995 3996 3997 04200 1377 RAMINIT: TAD [80.] ; the default terminal width is 80 3998 04201 3030 DCA WIDTH ; ... 3999 04202 3031 DCA LENGTH ; and automatic XOFF is disabled 4000 04203 6205 .PUSHJ @[CLRCPU] ; clear the saved user context 04204 5776 4001 04205 6205 .PUSHJ @[BPTCLR] ; clear the breakpoint tables 04206 5775 4002 04207 4527 JMS @ZPUSHJ1 ; (cross field call) 4003 04210 1713 INIPMP ; initialize the IDE disk partition map 4004 04211 6222 CIF 2 4005 04212 5774 JMP @[RDPSS] ; if NVRAM present, possibly overwrite some 4006 ; of these settings with stored ones 4007 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 94 FL Command - Flash download BTS6120.PLX 4008 .TITLE FL Command - Flash download 4009 4010 ; 4011 ; Flash command codes for 28Fx00 type EEPROMS 4012 ; 4013 7777 FCMDRA=7777 4014 0220 FCMDRI=0220 4015 0120 FCMDCS=0120 4016 0040 FCMDERA1=0040 4017 0320 FCMDERA2=0320 4018 0100 FCMDPROG=0100 4019 4020 ; Enter here for the FL command... It uses the same download code 4021 ; as DL and RL, but checks for presence of flash and prompts for 4022 ; overwriting it before executing that. 4023 4024 04213 6403 FLLOAD: MM3 ; access flash (if it's there) 4025 04214 6211 CDF 1 4026 4027 ; We want to check that a flash ROM is actually there. This is a bit 4028 ; problematic because the Read ID command returns a manufacturer and 4029 ; device code that are basically arbitrary. However, at least the commands 4030 ; seem to be the same for all flash devices in this class. 4031 ; What we'll do is try switching between array read and ID read mode a 4032 ; couple of times and see if the results are consistent with a flash ROM 4033 ; being there. 4034 4035 04215 1373 TAD [FCMDRA] ; reset flash to array read mode 4036 04216 3772 DCA @[0] 4037 4038 04217 1772 TAD @[0] ; array read mode - hash and stash 4039 04220 7002 BSW 4040 04221 1771 TAD @[2] 4041 04222 3041 DCA LOW 4042 4043 04223 1370 TAD [FCMDRI] ; set flash to read ID mode 4044 04224 3772 DCA @[0] 4045 4046 04225 1772 TAD @[0] ; fetch 1st ID byte 4047 04226 7002 BSW 4048 04227 1771 TAD @[2] ; combine with 2nd ID byte 4049 04230 3040 DCA HIGH 4050 4051 04231 1373 TAD [FCMDRA] ; reset flash to array read mode 4052 04232 3772 DCA @[0] 4053 4054 04233 1772 TAD @[0] ; array read mode - hash and compare 4055 04234 7002 BSW ; with the last result 4056 04235 1771 TAD @[2] 4057 04236 7041 CIA 4058 04237 1041 TAD LOW 4059 04240 7440 SZA 4060 04241 5262 JMP BADFLR ; didn't match! 4061 4062 04242 1370 TAD [FCMDRI] ; set flash to read ID mode 4063 04243 3772 DCA @[0] 4064 4065 04244 1772 TAD @[0] ; fetch 1st ID byte 4066 04245 7002 BSW 4067 04246 1771 TAD @[2] ; combine with 2nd ID byte 4068 4069 04247 6402 MM2 ; back to normal memory access mode 4070 04250 6201 CDF 0 4071 4072 04251 7041 CIA ; compare with last result PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 95 FL Command - Flash download BTS6120.PLX 4073 04252 1040 TAD HIGH 4074 04253 7440 SZA 4075 04254 5262 JMP BADFLR ; didn't match! 4076 4077 04255 1041 TAD LOW ; now make sure that we got distinct 4078 04256 7041 CIA ; values from Read Array and Read ID 4079 04257 1040 TAD HIGH 4080 04260 7440 SZA 4081 04261 5265 JMP OKFLR ; different - everything looks okay! 4082 4083 04262 4507 BADFLR: JMS @ZINLMES ; display an error 4084 04263 4343 FLMSG1 4085 04264 5524 JMP @ZRESTA ; and back to prompt 4086 4087 04265 1373 OKFLR: TAD [FCMDRA] ; reset flash to array read mode 4088 04266 3772 DCA @[0] 4089 4090 04267 4507 JMS @ZINLMES ; prompt to make sure we want to do this... 4091 04270 4352 FLMSG2 4092 04271 6205 .PUSHJ @[CONFRM] ; go wait for a "Y" or "y" 04272 5767 4093 04273 7620 SNL CLA ; did they confirm? 4094 04274 5524 JMP @ZRESTA ; no - just abort now 4095 4096 ; and start the download 4097 4098 04275 1366 TAD [ROMWR] ; use the ROM write routine 4099 04276 3765 DCA @[WRPTR] ; ... 4100 04277 1135 TAD ZM256 ; and the record (block) size is 256 4101 04300 3071 DCA RECSIZ ; ... 4102 04301 5764 JMP @[DLOAD1] ; and off we go, no arguments please 4103 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 96 Field 0 Vector Table BTS6120.PLX 4104 .TITLE Field 0 Vector Table 4105 4106 4107 ; this is a very small stub that allows us to call functions in Field 0 4108 ; from Field 3. This is accomplished by making .POPJ return via here. 4109 4110 04302 6223 RET0F2: CXF 2 ; return to field 2 4111 04303 6225 .POPJ ; the address is already on the stack 4112 4113 04304 6233 RET0F3: CXF 3 ; return to field 3 4114 04305 6225 .POPJ ; the address is already on the stack 4115 4116 ; variable and functions that we may want to access or hook in this field 4117 ; codes: I=instruction pointer, V=variable, H=hook (CIF n, JMP @.+1, V) 4118 ; Add only to the *end* of this list, please! 4119 ; n.b. JMS linkage functions generally cannot be used here 4120 04306 F0VECTOR: 4121 04306 4304 RET0F3 ; I utility - return to field 0 (must be first) 4122 04307 0000 UPC ; V user program counter (saved by the hardware) 4123 04310 0001 UAC ; V user accumulator 4124 04311 0002 UFLAGS ; V user status (LINK, GT, IF, DF, etc) from GCF 4125 04312 0351 SYSIN9-1 ; H initialization just before monitor entered 4126 04313 7463 CONOUT ; I output a character, no processing 4127 04314 7552 CONIN ; I input a character, no processing, null if none 4128 04315 7400 OUTCHR ; I type a single character 4129 04316 7477 INCHRS ; I input a character, null if none 4130 04317 6322 TOCT4 ; I type an octal number 4131 04320 7104 CRLF ; I type a carriage return/line feed 4132 04321 6101 SPACMP ; I get the next non-blank command character 4133 04322 6103 SPACM0 ; I get a non-blank character starting with the current 4134 04323 6131 BACKUP ; I backup the command line pointer 4135 04324 6114 EOLTST ; I test current character for end of line 4136 04325 6112 EOLNXT ; I test the next character for end of line 4137 04326 0475 GET ; I get the next character from the command line 4138 04327 6720 OCTNW ; I scan an octal number 4139 04330 6441 RANGE ; I scan an address range (e.g. "0-7777") 4140 04331 0377 RESTA-1 ; H monitor restart vector 4141 04332 0453 COMERR ; I report a command syntax error and restart 4142 04333 6277 TDECNW ; I print an unsigned decimal number 4143 04334 2536 NODISK-1 ; H check for disk presence 4144 04335 1262 TYPEIR-1 ; H print the current IR 4145 04336 0007 UIR ; V user IR 4146 04337 0035 ADDR ; V start address returned from RANGE 4147 04340 0036 ADRFLD ; V start field returned from RANGE 4148 04341 0040 HIGH ; V end address returned from RANGE 4149 04342 0042 HGHFLD ; V end field returned from RANGE 4150 04343 7645 BTSTR1-1 ; H CPREQ signaled 4151 04344 0020 PARMAP ; V partition map 4152 04345 0034 RAMBAS ; V base offset - 1 for each RAM disk field 4153 04364 3540 04365 3554 04366 2600 04367 7025 04370 0220 04371 0002 04372 0000 04373 7777 04374 0201 04375 2026 04376 2312 04377 0120 4154 04400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 97 Call Routines in Field 1 BTS6120.PLX 4155 .TITLE Call Routines in Field 1 4156 4157 ; This routine will allow a routine in field zero to simulate a .PUSHJ 4158 ; to a routine in field one. Even better, when the routine in field one 4159 ; executes a .POPJ, the return will eventually be to field zero! The 4160 ; contents of the AC are preserved both ways across the call. 4161 ; 4162 ;CALL: 4163 ; JMS @ZPUSHJ1 ; cross field call 4164 ; ; address of a routine in field 1 4165 ; ; with the AC preserved across the call 4166 ; 4167 04400 0000 PUSHJ1: 0 ; call here with a JMS instruction 4168 04401 3217 DCA PUSHAC ; save the caller's AC for a minute 4169 04402 1600 TAD @PUSHJ1 ; then get caller's argument 4170 04403 3216 DCA F1ADDR ; that's the address of the routine to call 4171 04404 1200 TAD PUSHJ1 ; now get caller's return address 4172 04405 7001 IAC ; and skip over the argument 4173 04406 6215 .PUSH ; put that on the stack 4174 04407 7200 CLA ; (PUSH doesn't clear the AC!) 4175 04410 1377 TAD [POPJ1] ; the field one routine will return to 4176 04411 6215 .PUSH ; ... POPJ1: in field one 4177 04412 7200 CLA ; ... 4178 04413 1217 TAD PUSHAC ; restore the original AC contents 4179 04414 6213 CXF 1 ; call with IF = DF = 1 4180 04415 5616 JMP @.+1 ; and go to the code in field 1 4181 04416 F1ADDR: .BLOCK 1 ; gets the address of the field 1 routine 4182 04417 PUSHAC: .BLOCK 1 ; a temporary place to save the AC 4183 4184 ; When the routine in field one executes a .POPJ, it will actually return to 4185 ; the code at POPJ1: _in field one_ !! Since we've also stacked our original 4186 ; caller's return address, the code at POPJ1 really only needs to do two 4187 ; things, a "CXF 0" to return to field zero, and then another .POPJ. 4188 ; Unfortunately, this code has to live in field one, so you won't find it 4189 ; here! 4190 04577 0305 4191 04600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 98 Free Space for Future Expansion! BTS6120.PLX 4192 .TITLE Free Space for Future Expansion! 4193 4194 4195 ; space to put patch code for this field 4196 04600 F0PATCH: 4197 4198 05600 .PAGE 30-1 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 99 Front Panel Initialization BTS6120.PLX 4199 .TITLE Front Panel Initialization 4200 4201 4202 ; This routine will determine if a FP6120 front panel is attached and, if 4203 ; one is, will initialize it. If a front panel is present, the FPDTCT word 4204 ; will be set to a non-zero value. This serves as a flag to control the 4205 ; actions of all the other front panel code. 4206 05600 7200 FPINIT: CLA ; clear all the FP variables anyway 4207 05601 3057 DCA FNSTAT ; just in case 4208 05602 3060 DCA BTSWCN ; ... 4209 05603 3061 DCA FPPGMM ; ... 4210 4211 ; If a front panel is installed, then the CCPR IOT will not only clear 4212 ; the CP timer and HALTSW flags, but it will also clear the AC as well. 4213 ; If no front panel is present, then CCPR is a no-op. That's an easy 4214 ; way to determine if a FP6120 is present. 4215 05604 7240 STA ; set the AC to -1 4216 05605 6430 CCPR ; clear the AC if an FP is present 4217 05606 7040 CMA ; 0 if no FP, -1 if an FP 4218 05607 3056 DCA FPDTCT ; and set the flag 4219 05610 1056 TAD FPDTCT ; get it back again 4220 05611 7650 SNA CLA ; if there's no front panel 4221 05612 6225 .POPJ ; then we can quit now 4222 4223 ; Just for fun, we display "6120" (in octal, of course) on the ADDRESS 4224 ; LEDs and our BTS6120 version on the DATA LEDs. Unfortunately this works 4225 ; only if the rotary switch is set to MD - you might think it would be easy 4226 ; to make it work for the other positions by adding a WSR here, but it's 4227 ; not that simple. If the rotary switch is set to PS, AC or MQ anything we 4228 ; write there will be overwritten by the UPDISP routine before you ever see 4229 ; it. Sorry. By the way, this rather causually corrupts a word of memory, 4230 ; but this routine is supposed to be used only during initialization anyway... 4231 05613 6266 CPD ; write to main memory 4232 05614 1377 TAD [VERSION] ; get our version number 4233 05615 3776 DCA @[6120] ; and write it to location 6120 4234 05616 6276 SPD ; back to panel data mode 4235 05617 6435 RLOF ; lastly, turn the RUN LED off 4236 05620 6225 .POPJ ; that'll be enough fun for today PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 100 Scan Front Panel Switches BTS6120.PLX 4237 .TITLE Scan Front Panel Switches 4238 4239 4240 ; This routine will scan all front panel switches, except for HALT and the 4241 ; rotary switch, and look for work to be done. The HALT switch is ignored 4242 ; until we give a command that will transfer control to main memory (e.g. 4243 ; CONTINUE or BOOT), and the rotary switch is handled by the data display 4244 ; update routine. 4245 ; 4246 ; Note that this routine is called only while we're in panel mode and 4247 ; BTS6120 is active - it's never called by the CP timer. The panel switches 4248 ; (except for HALT and the rotary switch) do nothing while a main memory 4249 ; program is running. 4250 05621 1056 SWSCAN: TAD FPDTCT ; get the front panel flag 4251 05622 7650 SNA CLA ; skip if a panel is attached 4252 05623 6225 .POPJ ; no panel - just quit now 4253 05624 6434 RFNS ; read the state of the function switches 4254 05625 0375 AND [7740] ; isolate the switches we know about 4255 05626 7041 CIA ; has there been any change in switch state 4256 05627 1057 TAD FNSTAT ; ... since we were last here? 4257 05630 6432 SPLK ; ignore everything if PANEL LOCK is on! 4258 05631 7650 SNA CLA ; (switches changed ???) 4259 05632 6225 .POPJ ; no (or PANEL LOCK) - there's nothing to do 4260 4261 ; Now that we've detected a change in the switch state, delay for 4262 ; approximately 10-15 milliseconds to allow the switch to stop bouncing. 4263 ; Remember - this code is used only when we're in panel mode; it's never 4264 ; called by the CP timer, so the delay is inconsequential. 4265 ; 4266 ; Each iteration of the delay loop requires 17 minor cycles, or 4.25us 4267 ; with a 8Mhz clock (6.8us at 5Mhz). A 15 ms delay therefore needs 3529 4268 ; iterations (again, assuming an 8Mhz clock). 4269 05633 1374 TAD [-3529.] ; initialize the timer 4270 05634 7001 SWSCA1: IAC ; [6] increment the AC 4271 05635 7440 SZA ; [7] has it overflowed yet? 4272 05636 5234 JMP SWSCA1 ; [4] nope - keep looping 4273 4274 ; Compute (.NOT. ) .AND. - this function gives a 4275 ; 1 bit for every switch which was not pressed before and is pressed now; 4276 ; those are the ones we want to process! 4277 05637 6434 RFNS ; read the current state 4278 05640 0375 AND [7740] ; mask off the unimportant switches 4279 05641 3301 DCA SWTEMP ; save it for a moment 4280 05642 1057 TAD FNSTAT ; get the old state 4281 05643 7040 CMA ; complement 4282 05644 0301 AND SWTEMP ; not old and new 4283 05645 7421 MQL ; save _that_ too 4284 05646 1301 TAD SWTEMP ; lastly update FNSTAT 4285 05647 3057 DCA FNSTAT ; ... for next time around 4286 05650 7701 ACL ; restore the changed switch map 4287 05651 7450 SNA ; if there are no one bits 4288 05652 6225 .POPJ ; then we've got nothing to do! 4289 4290 ; Now figure out which switch is set. It's not really clear what we should 4291 ; do if more than one switch is depressed at the same time (does a real -8 4292 ; have N key rollover for the front panel?) - in this case we just process 4293 ; the first switch that we detect and ignore the rest. 4294 05653 7004 RAL ; put BOOT in LINK and LA in AC0 4295 05654 7430 SZL ; is BOOT pressed? 4296 05655 5773 JMP @[SWBOOT] ; ... 4297 05656 7421 MQL ; save the bits again 4298 05657 3060 DCA BTSWCN ; clear the BOOT count for any key 4299 05660 7701 ACL ; ... _other_ than BOOT 4300 05661 7510 SPA ; what about LA ? 4301 05662 5302 JMP SWLA ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 101 Scan Front Panel Switches BTS6120.PLX 4302 05663 7006 RTL ; get the next two bits 4303 05664 7430 SZL ; next up is LXA 4304 05665 5311 JMP SWLXA ; ... 4305 05666 7510 SPA ; and after that is CLEAR 4306 05667 5772 JMP @[SWCLR] ; ... 4307 05670 7006 RTL ; position the next bits 4308 05671 7430 SZL ; this position is CONTINUE 4309 05672 5771 JMP @[CONT] ; (CONTINUE is exactly C command) 4310 05673 7510 SPA ; and then EXAM 4311 05674 5335 JMP SWEXA ; .... 4312 05675 7004 RAL ; only one left! 4313 05676 7710 SPA CLA ; the last one is DEP 4314 05677 5325 JMP SWDEP ; ... 4315 05700 6225 .POPJ ; it should be impossible to get here! 4316 4317 ; Temporary storage... 4318 05701 0000 SWTEMP: 0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 102 FP LA, LXA, EXAMINE and DEPOSIT Switches BTS6120.PLX 4319 .TITLE FP LA, LXA, EXAMINE and DEPOSIT Switches 4320 4321 4322 ; The LOAD ADDRess switch loads the switches (data switches, this time) 4323 ; into the PC and then displays (if the rotary switch is set to MD) the 4324 ; contents of the addressed location. 4325 05702 7604 SWLA: LAS ; read the switch register 4326 05703 3000 DCA UPC ; and deposit that in the PC 4327 05704 6205 .PUSHJ EXMEM ; display that location 05705 5351 4328 05706 6205 .PUSHJ @[TYPEPC] ; type the PC too 05707 5770 4329 05710 5506 JMP @ZCRLF ; finish the line and exit 4330 4331 4332 ; The LOAD EXTenDed ADDRess switch loads SR9..11 into the user's data 4333 ; field and SR7..9 into the user's instruction field. This is similar 4334 ; to loading the flags register, however the upper six bits are unchanged. 4335 05711 7604 SWLXA: LAS ; read the switch register 4336 05712 0367 AND [77] ; keep only the lower six bits 4337 05713 7421 MQL ; save that for a moment 4338 05714 1002 TAD UFLAGS ; get the last user mode flags 4339 05715 0366 AND [7700] ; keep the upper six bits of that 4340 05716 7501 MQA ; put the two together 4341 05717 3002 DCA UFLAGS ; and update the IF/DF 4342 05720 6205 .PUSHJ EXMEM ; display that location 05721 5351 4343 05722 6205 .PUSHJ @[TYPEPS] ; and type it on the console too 05723 5765 4344 05724 5506 JMP @ZCRLF ; finish the line and exit 4345 4346 4347 ; The DEPosit switch writes SR0..11 to the memory location addressed by 4348 ; the PC, increments the PC (but not the IF!) and then displays the contents 4349 ; of the next location. 4350 05725 6205 SWDEP: .PUSHJ @[USERDF] ; change DF to the last user mode IF 05726 5764 4351 05727 6266 CPD ; address main memory 4352 05730 7604 LAS ; read the data switch register 4353 05731 3400 DCA @UPC ; deposit them into memory 4354 05732 2000 ISZ UPC ; increment the memory address 4355 05733 7000 NOP ; ... 4356 05734 5341 JMP SWEXA1 ; and fall into the EXMEM routine 4357 4358 4359 ; The EXAMine switch increments the PC and then displays the memory location 4360 ; addressed by {IR,PC}. Note that the EXAM switch always does the same thing, 4361 ; however the data display only shows the memory data if the rotary switch is 4362 ; set to MD! 4363 05735 2000 SWEXA: ISZ UPC ; no - increment the user PC 4364 05736 7000 NOP ; ignore any wrap around 4365 05737 6205 .PUSHJ EXMEM ; display that location on the lights 05740 5351 4366 05741 1000 SWEXA1: TAD UPC ; fix up the PC and IF 4367 05742 3035 DCA ADDR ; ... for TMEM 4368 05743 1002 TAD UFLAGS ; ... 4369 05744 0131 AND ZK70 ; ... 4370 05745 3036 DCA ADRFLD ; ... 4371 05746 6205 .PUSHJ @[TMEM] ; type it on the console too 05747 5763 4372 05750 5506 JMP @ZCRLF ; ... 4373 4374 4375 ; This routine displays the location addressed by {IF,PC}. It's used 4376 ; by all the examine, load address and deposit routines... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 103 FP LA, LXA, EXAMINE and DEPOSIT Switches BTS6120.PLX 4377 05751 6205 EXMEM: .PUSHJ @[USERDF] ; change DF to the last user mode IF 05752 5764 4378 05753 6266 CPD ; address main memory next 4379 05754 1400 TAD @UPC ; and read the location at {IF,PC} 4380 05755 7200 CLA ; we don't actually care what we read! 4381 05756 6276 SPD ; back to panel memory 4382 05757 6201 CDF 0 ; ... 4383 05760 6225 .POPJ ; and we're done... 4384 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 0266 4385 06000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 104 Change Current DF to User's IF BTS6120.PLX 4386 .TITLE Change Current DF to User's IF 4387 4388 4389 ; This routine will change the current data field to the user's instruction 4390 ; field, as determined by the last user mode PS in UFLAGS... 4391 06000 7200 USERDF: CLA ; just in case! 4392 06001 1002 TAD UFLAGS ; get the last user mode flags 4393 06002 0131 AND ZK70 ; isolate just the instruction field 4394 06003 1377 TAD [CDF 0] ; make a CDF instruction out of it 4395 06004 3205 DCA .+1 ; and execute that 4396 06005 7000 NOP ; (gets overwritten with a CDF instruction) 4397 06006 6225 .POPJ ; return and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 105 START, CONTINUE and BOOT Switches BTS6120.PLX 4398 .TITLE START, CONTINUE and BOOT Switches 4399 4400 4401 ; The BOOT switch (what else?) boots the PDP-8. Because BOOT is a fairly 4402 ; dangerous function, we steal a cue from the PDP-8/A and require it to be 4403 ; pressed _twice_ in succession before anything happens. The flag BTSWCN 4404 ; (BooT SWitch CouNt) keeps track of the number of times BOOT has been 4405 ; pressed. 4406 ; 4407 ; Note that the BOOT switch ignores the state of the RUN/HALT switch (i.e. 4408 ; it doesn't single step if the HALT switch is down). That seems like the 4409 ; most useful behavior. 4410 06007 2060 SWBOOT: ISZ BTSWCN ; have we been here before (recently)? 4411 06010 5214 JMP SWBOO1 ; no - wait for a second toggle 4412 06011 6205 .PUSHJ @ZCRLF ; ... 06012 5506 4413 06013 5776 JMP @[BOOT1] ; yes - go find something to boot! 4414 4415 ; Here for the first toggle of two... 4416 06014 7240 SWBOO1: STA ; set the AC to -1 4417 06015 3060 DCA BTSWCN ; and set the counter for next time 4418 06016 6225 .POPJ ; do nothing else this time 4419 4420 4421 ; The CLEAR key clears the AC and other processor registers and then 4422 ; asserts IOCLR L. It also clears the flag bits in the PS, but it leaves 4423 ; the IF, DF and PC alone. It does _not_ (contrary to what I once thought) 4424 ; actually start execution! 4425 06017 3004 SWCLR: DCA USP1 ; clear both stack pointers 4426 06020 3005 DCA USP2 ; ... 4427 06021 3003 DCA UMQ ; the multiplier quotient 4428 06022 3001 DCA UAC ; and the AC 4429 06023 1002 TAD UFLAGS ; get the current flags 4430 06024 0375 AND [77] ; clear all but the IF and DF 4431 06025 3002 DCA UFLAGS ; ... 4432 06026 3061 DCA FPPGMM ; clear the front panel program mode 4433 06027 6007 CAF ; finally, assert IOCLR L 4434 06030 6225 .POPJ ; all done! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 106 HALT Switch BTS6120.PLX 4435 .TITLE HALT Switch 4436 4437 4438 ; This routine will test the state of the front panel HALT switch and 4439 ; take the skip return if it is in the RUN (i.e. UP) position. If the 4440 ; switch is in the HALT (DOWN) position, then commands that would normally 4441 ; start a main memory program (e.g. STart, Continue, etc) single step 4442 ; instead. 4443 ; 4444 ; If no front panel is installed, this routine always takes the skip 4445 ; (i.e. RUN) return! 4446 ; 4447 ; NOTE that this routine must be called with a JMS and not the usual 4448 ; PUSHJ/POPJ combination! 4449 06031 0000 CHKHLT: 0 ; call here with a JMS! 4450 06032 7300 CLA CLL ; just in case 4451 06033 1056 TAD FPDTCT ; any front panel installed? 4452 06034 7650 SNA CLA ; skip if a FP6120 is present 4453 06035 5242 JMP CHKHL1 ; nope - take the skip return now 4454 06036 6434 RFNS ; read the function switches 4455 06037 0374 AND [20] ; isolate the halt switch bit 4456 06040 6432 SPLK ; ignore it if PANEL LOCK is on! 4457 06041 7640 SZA CLA ; HALT is 1 for UP, 0 for DOWN 4458 06042 2231 CHKHL1: ISZ CHKHLT ; switch is UP, take the skip return 4459 06043 5631 JMP @CHKHLT ; and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 107 Update the Front Panel Data Display BTS6120.PLX 4460 .TITLE Update the Front Panel Data Display 4461 4462 4463 ; This routine will read the rotary switch position and display the 4464 ; selected data on the data LEDs. There are a couple of points to 4465 ; keep in mind while you read this: 4466 ; 4467 ; * The display is selected by the 4 least significant bits returned 4468 ; by the RFNS IOT. Exactly _one_ of these bits will be a one! 4469 ; 4470 ; * The MD DISP position is handled by the hardware and requires no 4471 ; action on our part. Actually the CP timer interrupt is disabled 4472 ; when the switch is in the MD DISP position, but that doesn't 4473 ; guarantee that this routine won't be called from somewhere else. 4474 ; 4475 ; * If the FPPGMM (Front Panel Program Mode) flag is non-zero, then the 4476 ; main memory program is controlling the data display and, rather than 4477 ; displaying any of the registers, we display the contents of FPPGMD. 4478 ; Of course, this works only if the rotary switch is NOT set to MD! 4479 ; 4480 ; * Since this routine is also called by the 30Hz timer, we want it 4481 ; to be as fast as possible! 4482 ; 4483 06044 1056 UPDISP: TAD FPDTCT ; get the front panel flag 4484 06045 7650 SNA CLA ; is a front panel attached? 4485 06046 6225 .POPJ ; nope - just quit now 4486 06047 1061 TAD FPPGMM ; front panel program mode? 4487 06050 7640 SZA CLA ; skip if not 4488 06051 5277 JMP PGMDSP ; yes - display the program data only 4489 06052 6434 RFNS ; read the rotary switch 4490 06053 7010 RAR ; put MD DISP L in the link 4491 06054 7430 SZL ; is it set? 4492 06055 5267 JMP UPDIS2 ; yes - no action required 4493 06056 7010 RAR ; test MQ DISP next 4494 06057 7430 SZL ; ??? 4495 06060 5274 JMP MQDISP ; that's the one - go show the MQ 4496 06061 7010 RAR ; next up is AC DISP 4497 06062 7430 SZL ; ??? 4498 06063 5271 JMP ACDISP ; ... 4499 4500 ; The last bit is PS (FLAGS) DISP which, unless the FP hardware is 4501 ; broken, _MUST_ be set. There's no point in checking - just do it! 4502 06064 7200 PSDISP: CLA ; ... 4503 06065 1002 TAD UFLAGS ; get the user mode flags 4504 06066 6246 UPDIS1: WSR ; display then on the lights 4505 06067 7300 UPDIS2: CLA CLL ; (just in case!) 4506 06070 6225 .POPJ ; and we're outta here 4507 4508 ; Here to display the AC on the lights... 4509 06071 7200 ACDISP: CLA ; ... 4510 06072 1001 TAD UAC ; display the last user mode AC 4511 06073 5266 JMP UPDIS1 ; ... 4512 4513 ; And here to display the MQ... 4514 06074 7200 MQDISP: CLA ; ... 4515 06075 1003 TAD UMQ ; display the last user mode MQ 4516 06076 5266 JMP UPDIS1 ; ... 4517 4518 ; Here to display the program data.. 4519 06077 1062 PGMDSP: TAD FPPGMD ; get the program data 4520 06100 5266 JMP UPDIS1 ; display it and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 108 Simple Lexical Functions BTS6120.PLX 4521 .TITLE Simple Lexical Functions 4522 4523 4524 ; This routine will skip over any spaces in the command line and return the 4525 ; next non-space character in the AC and SAVCHR... 4526 4527 ; Here to start skipping with the next character... 4528 06101 6205 SPACMP: .PUSHJ @ZGET ; Get the next character 06102 5515 4529 4530 ; Here to consider the current character and then skip... 4531 06103 7200 SPACM0: CLA ; Be sure the AC is safe to use 4532 06104 1050 TAD SAVCHR ; And look at the current character 4533 06105 1133 TAD ZMSPACE ; Compare it to a space 4534 06106 7650 SNA CLA ; ??? 4535 06107 5301 JMP SPACMP ; Keep going until we don't find one 4536 06110 1050 TAD SAVCHR ; Restore the character 4537 06111 6225 .POPJ ; And we're all done 4538 4539 ; This routine will examine the current character (in SAVCHR) or the next 4540 ; character (via GET) for end of line, which is stored as a null byte). If 4541 ; it isn't the EOL, then COMERR is called and the current command is aborted, 4542 ; otherwise this routine just returns... 4543 4544 ; Enter here to examine the next character... 4545 06112 6205 EOLNXT: .PUSHJ @ZGET ; Load the next character 06113 5515 4546 ; Then fall into the current character test 4547 4548 ; Enter here to examine the current character... 4549 06114 6205 EOLTST: .PUSHJ @ZSPACM0 ; Allow blanks at the end of the line 06115 5511 4550 06116 7640 SZA CLA ; Is it the end of the line ?? 4551 06117 5525 JMP @ZCOMERR ; No -- that's bad 4552 06120 6225 .POPJ ; Yes -- that's good 4553 4554 ; This routine will test either the current character (via SAVCHR) or the 4555 ; next character (via GET) to see if it's a space. If it isn't, then it 4556 ; jumps to COMERR and aborts the current command... 4557 4558 ; Enter here to examine the next character... 4559 06121 6205 SPANXT: .PUSHJ @ZGET ; get the next character 06122 5515 4560 ; and fall into SPATST... 4561 4562 ; Enter here to examine the current character 4563 06123 7200 SPATST: CLA ; don't require that the AC be cleared 4564 06124 1050 TAD SAVCHR ; get the current character 4565 06125 1133 TAD ZMSPACE ; and compare it to a space 4566 06126 7640 SZA CLA ; well?? 4567 06127 5525 JMP @ZCOMERR ; not equal - this is a bad command line 4568 06130 6225 .POPJ ; it's a space 4569 4570 4571 ; This routine will backup the command scanner so that the character 4572 ; just read will be read again with the next call to GET... 4573 06131 7240 BACKUP: STA ; Load the AC with -1 4574 06132 1013 TAD L ; Then decrement the line pointer 4575 06133 3013 DCA L ; ... 4576 06134 6225 .POPJ ; That's all it takes 4577 06174 0020 06175 0077 06176 2452 06177 6201 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 109 Simple Lexical Functions BTS6120.PLX 4578 06200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 110 Type ASCII Strings BTS6120.PLX 4579 .TITLE Type ASCII Strings 4580 4581 4582 ; This routine will type a ASCIZ string stored in field 1 using the standard 4583 ; OS/8 "3 for 2" packing system. This format is used by the monitor to store 4584 ; help and error messages. On call, the address of the string is passed in the 4585 ; AC and, on return, the AC will always be cleared. 4586 06200 1377 OUTSTR: TAD [-1] ; auto index registers pre-increment 4587 06201 3010 DCA X1 ; ... 4588 06202 7346 NLM3 ; load the AC with -3 4589 06203 3070 DCA DIGITS ; and initialize the character counter 4590 4591 ; Get the next character and output it... 4592 06204 6211 OUTST1: CDF 1 ; strings always live in field 1 4593 06205 2070 ISZ DIGITS ; which character are we on? 4594 06206 5227 JMP OUTST2 ; first or second - they're easy 4595 4596 ; Extract the third character from a triplet... 4597 06207 7346 NLM3 ; re-initialize the character counter 4598 06210 3070 DCA DIGITS ; ... 4599 06211 7344 NLM2 ; then load the AC with -2 4600 06212 1010 TAD X1 ; and backup the string pointer 4601 06213 3010 DCA X1 ; ... 4602 06214 1410 TAD @X1 ; get the first word of the pair 4603 06215 0135 AND ZK7400 ; get the upper four bits of the word 4604 06216 7002 BSW ; position them in the upper bits of the byte 4605 06217 7106 CLL RTL ; ... 4606 06220 7421 MQL ; save it in the MQ for a while 4607 06221 1410 TAD @X1 ; then get the second word again 4608 06222 0135 AND ZK7400 ; the upper four bits again 4609 06223 7002 BSW ; become the lower for bits of the byte 4610 06224 7112 CLL RTR ; ... 4611 06225 7501 MQA ; put the byte together 4612 06226 5230 JMP OUTST3 ; and type it normally 4613 4614 ; Here for the first or second character of a triplet... 4615 06227 1410 OUTST2: TAD @X1 ; get the character 4616 06230 0130 OUTST3: AND ZK177 ; trim it to just seven bits 4617 06231 6201 CDF 0 ; restore the original data field 4618 06232 7450 SNA ; end of string ? 4619 06233 6225 .POPJ ; yes - we can quit now 4620 06234 6205 .PUSHJ @ZOUTCHR ; nope - type this one too 06235 5474 4621 06236 5204 JMP OUTST1 ; and go do the next 4622 4623 ; This routine does exactly the same thing as OUTSTR, except that it allows 4624 ; the message pointer to be passed in line, via a JMS instruction 4625 06237 0000 INLMES: 0 ; call here via a JMS instruction 4626 06240 7200 CLA ; ... 4627 06241 1637 TAD @INLMES ; fetch the string address 4628 06242 6205 .PUSHJ OUTSTR ; type it out 06243 5200 4629 06244 2237 ISZ INLMES ; skip over the address 4630 06245 5637 JMP @INLMES ; and return 4631 4632 ; This routine will type an ASCIZ string, packed one character per word and 4633 ; terminated with a null character, on the terminal. The address of the 4634 ; string, -1, should be loaded into the AC before calling this routine, and 4635 ; the AC will always be cleared on return. 4636 06246 3010 TASCIZ: DCA X1 ; save the pointer to the string 4637 06247 1410 TASCI1: TAD @X1 ; and get the first character 4638 06250 7450 SNA ; is this the end of the string ?? 4639 06251 6225 .POPJ ; yes -- quit now 4640 06252 6205 .PUSHJ @ZOUTCHR ; no -- type this character 06253 5474 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 111 Type ASCII Strings BTS6120.PLX 4641 06254 5247 JMP TASCI1 ; and then loop until the end 4642 4643 ; This routine is identical to TASCIZ, except that the string is stored in 4644 ; field 1, rather than field 0... 4645 06255 3010 TASZF1: DCA X1 ; save the pointer to the string 4646 06256 6211 CDF 1 ; the string is in field 1 4647 06257 1410 TAD @X1 ; and get the next character 4648 06260 6201 CDF 0 ; back to our field 4649 06261 7450 SNA ; is this the end of the string ?? 4650 06262 6225 .POPJ ; yes -- quit now 4651 06263 6205 .PUSHJ @ZOUTCHR ; no -- type this character 06264 5474 4652 06265 5256 JMP TASZF1+1 ; and then loop until the end PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 112 Type SIXBIT Words, and Characters BTS6120.PLX 4653 .TITLE Type SIXBIT Words, and Characters 4654 4655 4656 ; This routine will type the two character SIXBIT word contained in the AC. 4657 ; It always types exactly two characters, so if the second character is a null 4658 ; (00), then a trailing blank appears. The AC is cleared on return. 4659 06266 3065 TSIXW: DCA WORD ; Save the 2 characters 4660 06267 1065 TAD WORD ; And get them back 4661 06270 7002 BSW ; Position the first one 4662 06271 6205 .PUSHJ TSIXC ; And type it out 06272 5274 4663 06273 1065 TAD WORD ; No -- get the second character 4664 ; And fall into the TSIXC routine 4665 4666 ; This routine will type a single SIXBIT character from the right 4667 ; byte of the AC. The AC will be cleared on return. 4668 06274 0376 TSIXC: AND [77] ; Trim the character to just 6 bits 4669 06275 1375 TAD [" "] ; No -- convert the character to ASCII 4670 06276 5774 JMP @[THCHAR] ; And type it out PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 113 Type Decimal Numbers BTS6120.PLX 4671 .TITLE Type Decimal Numbers 4672 4673 4674 ; This routine will type the contents of the AC in decimal. It always 4675 ; treats the AC as an unsigned quantity and will type numbers from 0 to 4095. 4676 ; It uses locations WORD and COUNT and the AC is always cleared on return. 4677 06277 3065 TDECNW: DCA WORD ; remember the number to be typed 4678 06300 3070 DCA DIGITS ; and clear the quotient 4679 06301 1065 TAD WORD ; get the dividend back again 4680 4681 ; Divide by 10 via repeated subtraction... 4682 06302 7100 TDECN1: CLL ; make sure the LINK is clear 4683 06303 1373 TAD [-10.] ; subtract 10 from the dividend 4684 06304 7420 SNL ; did it fit ??? 4685 06305 5310 JMP TDECN2 ; no -- go get the remainder 4686 06306 2070 ISZ DIGITS ; yes -- increment the quotient 4687 06307 5302 JMP TDECN1 ; and keep dividing 4688 4689 ; Now figure the remainder... 4690 06310 1372 TDECN2: TAD [10.] ; correct the remainder 4691 06311 6215 .PUSH ; and save it on the stack 4692 06312 7200 CLA ; get the quotient 4693 06313 1070 TAD DIGITS ; ... 4694 06314 7450 SNA ; is it zero ??? 4695 06315 5320 JMP TDECN3 ; yes -- proceed 4696 06316 6205 .PUSHJ TDECNW ; no type that part first 06317 5277 4697 4698 ; Here to type the digit and return... 4699 06320 6235 TDECN3: .POP ; restore the remainder 4700 06321 5771 JMP @[TDIGIT] ; type it in ASCII and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 114 Type Octal Numbers BTS6120.PLX 4701 .TITLE Type Octal Numbers 4702 4703 4704 ; This routine will type a 4 digit octal number passed in the AC. It always 4705 ; prints exactly four digits, with leading zeros added as necessary. The AC 4706 ; will be cleared on return. 4707 06322 3065 TOCT4: DCA WORD ; save the number to type 4708 06323 1370 TAD [-4] ; and get the number of iterations 4709 06324 3070 TOCTN: DCA DIGITS ; ... 4710 4711 ; Extract one digit and print it... 4712 06325 1065 TOCTL: TAD WORD ; get the remaining bits 4713 06326 7106 CLL RTL ; shift them left 2 bits 4714 06327 7006 RTL ; and then 2 more (remember the link!) 4715 06330 3050 DCA SAVCHR ; remember that for a later 4716 06331 1050 TAD SAVCHR ; and we also need it now 4717 06332 7010 RAR ; restore the extra bit (in the link) 4718 06333 3065 DCA WORD ; then remember the remaining bits 4719 06334 1050 TAD SAVCHR ; get the digit back 4720 06335 0132 AND ZK7 ; trim it to just 3 bits 4721 06336 6205 .PUSHJ @[TDIGIT] ; type it out 06337 5771 4722 4723 ; Here after we have typed another digit... 4724 06340 2070 ISZ DIGITS ; is this enough ?? 4725 06341 5325 JMP TOCTL ; no -- keep typing 4726 06342 6225 .POPJ ; yes -- quit now 4727 4728 ; This routine is identical to TOCT4, except that it types only three digits 4729 ; with leading zeros. It's useful for printing eight bit quantities... 4730 06343 7014 TOCT3: R3L ; throw away the most significant digit 4731 06344 3065 DCA WORD ; save the value to be typed 4732 06345 7346 NLM3 ; get the number of iterations 4733 06346 5324 JMP TOCTN ; and join the regular code 4734 4735 ; This small routine will type an octal number in the AC followed by a space. 4736 06347 6205 TOCT4S: .PUSHJ TOCT4 ; then type the data in octal 06350 5322 4737 06351 5475 JMP @ZTSPACE ; finally type a space and return 4738 4739 ; This small routine will type an octal number from the AC followed by a CRLF. 4740 06352 6205 TOCT4C: .PUSHJ TOCT4 ; and type that in octal 06353 5322 4741 06354 5506 JMP @ZCRLF ; finish with a CRLF 4742 4743 06355 6205 TOCT4M: .PUSHJ TOCT4 ; and type that in octal 06356 5322 4744 06357 6205 .PUSHJ @ZCRLF ; finish with a CRLF 06360 5506 4745 06361 5524 JMP @ZRESTA 4746 06370 7774 06371 7102 06372 0012 06373 7766 06374 7427 06375 0040 06376 0077 06377 7777 4747 06400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 115 Type 15 Bit Addresses BTS6120.PLX 4748 .TITLE Type 15 Bit Addresses 4749 4750 4751 ; This routine will type a 15 bit address, passed in location ADDR, and with 4752 ; the field is in location ADRFLD. The address will be typed as a 5 digit 4753 ; octal number, and then followed by a "/" character and a space. The initial 4754 ; contents of the AC are ignored and the AC is always cleared on return. 4755 06400 7200 TADDR: CLA ; ... 4756 06401 1036 TAD ADRFLD ; get the high 3 bits of the address 4757 06402 6205 .PUSHJ @[TFIELD] ; type that out 06403 5777 4758 06404 1035 TAD ADDR ; then get the address 4759 06405 6205 .PUSHJ @ZTOCT4 ; and type all 12 bits of that 06406 5477 4760 06407 6205 .PUSHJ @[TSLASH] ; type a slash as a separator 06410 5776 4761 06411 5475 JMP @ZTSPACE ; finish with a space 4762 4763 ; This routine will type a single octal digit which represents a memory 4764 ; field. The field should be passed in the AC. 4765 06412 7010 TFIELD: RAR ; right justify the field number 4766 06413 7012 RTR ; ... 4767 06414 0132 AND ZK7 ; trim it to just 3 bits 4768 06415 5775 JMP @[TDIGIT] ; and fall into TDIGIT... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 116 Scan Addresses BTS6120.PLX 4769 .TITLE Scan Addresses 4770 4771 4772 ; This routine will read a 15 bit address into registers ADDR and ADRFLD. 4773 06416 6205 RDADDR: .PUSHJ @[OCTNF] ; read the 15 bit address 06417 5774 4774 06420 1065 TAD WORD ; get the low order bits 4775 06421 3035 DCA ADDR ; and put them in ADDR 4776 06422 6225 .POPJ ; that's it... 4777 4778 ; This routine will read a 15 bit address into registers HIGH and HGHFLD. 4779 06423 6205 RDHIGH: .PUSHJ RDADDR ; read a 15 bit address 06424 5216 4780 06425 1035 TAD ADDR ; get the low order bits 4781 06426 3040 DCA HIGH ; into HIGH 4782 06427 1036 TAD ADRFLD ; get the field 4783 06430 3042 DCA HGHFLD ; into HGHFLD 4784 06431 6225 .POPJ ; and that's all 4785 4786 ; This routine will read a 15 bit address into registers LOW AND LOWFLD. 4787 06432 6205 RDLOW: .PUSHJ RDADDR ; the same thing as before 06433 5216 4788 06434 1035 TAD ADDR ; ... 4789 06435 3041 DCA LOW ; only the names have changed 4790 06436 1036 TAD ADRFLD ; ... 4791 06437 3043 DCA LOWFLD ; ... 4792 06440 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 117 Scan an Address Range BTS6120.PLX 4793 .TITLE Scan an Address Range 4794 4795 4796 ; This routine will read either one or two octal numbers which describe a 4797 ; range of memory addresses. A range may be a single number (in which case 4798 ; the starting and ending values are the same) or two numbers with a space 4799 ; character between them (in which case the first number is the starting value 4800 ; and the last is the ending value). The starting value is always returned in 4801 ; locations LOW/LOWFLD and ADDR/ADRFLD, and the ending value is placed in 4802 ; HIGH/HGHFLD. If two addresses were seen, the LINK will be set upon return; 4803 ; it is cleared if only one address was found. 4804 06441 6205 RANGE: .PUSHJ RDLOW ; first read the low part of the range 06442 5232 4805 06443 6205 .PUSHJ @ZSPACM0 ; get the next non-space character 06444 5511 4806 06445 1373 TAD [-"-"] ; is it a range delimiter ?? 4807 06446 7640 SZA CLA ; ??? 4808 06447 5265 JMP RANGE1 ; no -- this must be the single address type 4809 4810 ; Here for a two address range... 4811 06450 6205 .PUSHJ RDHIGH ; go read the high order part of the range 06451 5223 4812 06452 1041 TAD LOW ; make ADDR point to the starting point 4813 06453 3035 DCA ADDR ; ... 4814 06454 1043 TAD LOWFLD ; ... 4815 06455 3036 DCA ADRFLD ; ... 4816 06456 6205 .PUSHJ TSTADR ; then be sure the numbers are in order 06457 5306 4817 06460 7020 CML ; ... 4818 06461 7630 SZL CLA ; ??? 4819 06462 6225 .POPJ ; yes -- return with the link set 4820 06463 4526 JMS @ZERROR ; no -- this isn't legal 4821 06464 3453 ERRRAN ; ?WRONG ORDER 4822 4823 ; Here for a single address range... 4824 06465 1041 RANGE1: TAD LOW ; set the high equal to the low 4825 06466 3040 DCA HIGH ; ... 4826 06467 1043 TAD LOWFLD ; ... 4827 06470 3042 DCA HGHFLD ; ... 4828 06471 7100 CLL ; Then return with the link cleared 4829 06472 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 118 Address Arithmetic BTS6120.PLX 4830 .TITLE Address Arithmetic 4831 4832 4833 ; This routine will increment the 15 bit address contained in registers 4834 ; ADDR and ADRFLD. If the address increments past 77777, the link will be 4835 ; 1 on return; otherwise it is always 0. 4836 06473 7300 NXTADR: CLA CLL ; ... 4837 06474 2035 ISZ ADDR ; increment the address 4838 06475 6225 .POPJ ; no wrap around -- leave the field alone 4839 06476 1036 TAD ADRFLD ; wrap around -- increment the field too 4840 06477 1372 TAD [-70] ; are we already in field 7 ?? 4841 06500 7510 SPA ; ??? 4842 06501 7020 CML ; no -- make the LINK be cleared on return 4843 06502 1371 TAD [70+10] ; restore and increment the field 4844 06503 0131 AND ZK70 ; only allow these bits in the result 4845 06504 3036 DCA ADRFLD ; and put it back 4846 06505 6225 .POPJ ; ... 4847 4848 ; This routine will compare the 15 bit address in registers ADDR and 4849 ; ADRFLD to the address in registers HIGH and HGHFLD. If ADDR/ADRFLD 4850 ; is less than HIGH/HGHFLD, the link will be zero on return. If ADDR/ADRFLD 4851 ; is greater then or equal to HIGH/HGHFLD, the link will be one. 4852 06506 7300 TSTADR: CLA CLL ; clear the AC and set L = 0 4853 06507 1036 TAD ADRFLD ; get the field 4854 06510 7061 CMA IAC CML ; negate the field and set L = 1 4855 06511 1042 TAD HGHFLD ; compare to the high field 4856 06512 7640 SZA CLA ; are they equal ?? 4857 06513 6225 .POPJ ; no -- the LINK has the correct status 4858 06514 1040 TAD HIGH ; yes -- compare the addresses 4859 06515 7041 CMA CIA ; L = 0 now 4860 06516 1035 TAD ADDR ; ... 4861 06517 7200 CLA ; clear the AC 4862 06520 6225 .POPJ ; but return the status in the LINK 4863 4864 ; This routine will swap the 15 bit address in ADDR/ADRFLD with the the 4865 ; 15 bit address in LOW/LOWFLD. The AC is always cleared. 4866 06521 7200 SWPADR: CLA ; ... 4867 06522 1041 TAD LOW ; get one value 4868 06523 7421 MQL ; and save it in the MQ 4869 06524 1035 TAD ADDR ; then get the other 4870 06525 3041 DCA LOW ; move it to the other place 4871 06526 7501 MQA ; and get the original one back 4872 06527 3035 DCA ADDR ; it goes in the second location 4873 06530 1043 TAD LOWFLD ; now do the same thing for fields 4874 06531 7421 MQL ; ... 4875 06532 1036 TAD ADRFLD ; ... 4876 06533 3043 DCA LOWFLD ; ... 4877 06534 7501 MQA ; ... 4878 06535 3036 DCA ADRFLD ; ... 4879 06536 6225 .POPJ ; that's all there is to it 4880 06571 0100 06572 7710 06573 7723 06574 7004 06575 7102 06576 7074 06577 6412 4881 06600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 119 Scan a Command Name BTS6120.PLX 4882 .TITLE Scan a Command Name 4883 4884 4885 ; This routine will scan a command or register name for the monitor. Names 4886 ; are always alphabetic, may not contain any digits, and are limited to one or 4887 ; two letters. The result is stored, in SIXBIT, in location NAME. One letter 4888 ; commands are left justified and padded on the right with zeros. If the end 4889 ; of line is the next character, then this routine will return with NAME set 4890 ; to zero and no error. If, however, there is a least one character out there 4891 ; and it is not a letter, then COMERR will be called... 4892 06600 7200 NAMENW: CLA ; be sure the AC is zero 4893 06601 3045 DCA NAME ; and clear the resulting name 4894 06602 6205 .PUSHJ @ZSPACMP ; get the next character, whatever it is 06603 5510 4895 06604 7450 SNA ; is there anything there ?? 4896 06605 6225 .POPJ ; no -- just give up now 4897 06606 6205 .PUSHJ ALPHA ; see if it is a letter 06607 5227 4898 06610 7420 SNL ; was it a letter ?? 4899 06611 5525 JMP @ZCOMERR ; no -- this isn't legal 4900 06612 1133 TAD ZMSPACE ; yes -- convert it to SIXBIT 4901 06613 7002 BSW ; left justify it 4902 06614 3045 DCA NAME ; and store it in word 4903 4904 ; Check for a second letter in the name... 4905 06615 6205 .PUSHJ @ZGET ; get the next character 06616 5515 4906 06617 6205 .PUSHJ ALPHA ; is this a letter ?? 06620 5227 4907 06621 7420 SNL ; ??? 4908 06622 5512 JMP @ZBACKUP ; no -- put it back and return 4909 06623 1133 TAD ZMSPACE ; yes -- convert it to SIXBIT too 4910 06624 1045 TAD NAME ; put both letters together 4911 06625 3045 DCA NAME ; ... 4912 06626 6225 .POPJ ; then that's all 4913 4914 ; This routine will return with the LINK bit set if the AC holds a letter, 4915 ; and with the LINK reset if it does not. In either case the AC is not 4916 ; disturbed... 4917 06627 7120 ALPHA: STL ; be sure the link starts in a known state 4918 06630 1377 TAD [-"A"] ; compare it to the first letter 4919 06631 7500 SMA ; skip if it isn't a letter 4920 06632 5235 JMP ALPHA1 ; it might be -- look further 4921 06633 1376 TAD ["A"] ; it's not a letter -- restore the AC 4922 06634 6225 .POPJ ; and quit (the link is zero now !!) 4923 4924 ; Here if it might be a letter (the link is also zero now)... 4925 06635 1375 ALPHA1: TAD ["A"-"Z"-1] ; now compare it to the other end 4926 06636 7500 SMA ; skip if it is a letter 4927 06637 7020 CML ; it isn't a letter -- set the link to a 0 4928 06640 1374 TAD ["Z"+1] ; restore the character and the link 4929 06641 6225 .POPJ ; then that's all PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 120 Command Lookup and Dispatch BTS6120.PLX 4930 .TITLE Command Lookup and Dispatch 4931 4932 4933 ; This routine will lookup a command or register name in a table and then 4934 ; dispatch to the corresponding routine. The address of the table, should 4935 ; be passed in the AC. The table is formatted as two word entries - the first 4936 ; word of a pair is the SIXBIT name of the command or register, and the second 4937 ; word is the address of the routine to call. As soon as this routine finds a 4938 ; first word that matches the value currently in NAME, it will jump to the 4939 ; routine indicated by the second word. The table ends with a zero word 4940 ; followed by the address of an error routine - the zero word always matches 4941 ; the current name and the error routine will be called. 4942 ; 4943 ; NOTE: Command tables are always stored in field one, however the addresses 4944 ; of all the routines they reference are always in field zero! 4945 ; 4946 ; NOTE: Auto index registers pre-decrement, so the address -1 of the table 4947 ; must be passed in the AC! 4948 06642 3010 MATCH: DCA X1 ; save the pointer to the table 4949 06643 6211 CDF 1 ; command tables are stored in field 1 4950 4951 ; Search for a name which matches... 4952 06644 1410 MATCH1: TAD @X1 ; pick up the name (from field 1) 4953 06645 7450 SNA ; is this the end of the table ?? 4954 06646 5255 JMP MATCH2 ; yes -- this always matches 4955 06647 7041 CIA ; make the word negative 4956 06650 1045 TAD NAME ; and compare it to the desired value 4957 06651 7650 SNA CLA ; ??? 4958 06652 5255 JMP MATCH2 ; a match !! 4959 06653 2010 ISZ X1 ; no match -- skip over the address 4960 06654 5244 JMP MATCH1 ; and keep looking 4961 4962 ; Here when we find a match... 4963 06655 1410 MATCH2: TAD @X1 ; get the address of the routine 4964 06656 3261 DCA MATCH3 ; put that in a safe place 4965 06657 6201 CDF 0 ; change back to the usual data field 4966 06660 5661 JMP @MATCH3 ; then branch to the right routine 4967 4968 ; Temporary storage for MATCH... 4969 06661 MATCH3: .BLOCK 1 ; address of the matching routine PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 121 Scan Decimal Numbers BTS6120.PLX 4970 .TITLE Scan Decimal Numbers 4971 4972 4973 ; This routine will read a decimal number from the command line and return 4974 ; its value in location WORD. The value is limited to 12 bits and overflows 4975 ; are not detected. At least one decimal digit must be found on the command 4976 ; line or COMERR will be called, and the first non-digit character found will 4977 ; be returned in location SAVCHR. 4978 06662 7200 DECNW: CLA ; ignore the AC initially 4979 06663 3065 DCA WORD ; clear the total 4980 06664 3070 DCA DIGITS ; and the digit counter 4981 06665 6205 .PUSHJ @ZSPACMP ; ignore any leading blanks 06666 5510 4982 4983 ; Check for a decimal digit... 4984 06667 1373 DECNW1: TAD [-"0"] ; compare it to zero 4985 06670 7510 SPA ; ??? 4986 06671 5313 JMP DECNW2 ; it's not a digit -- quit 4987 06672 1372 TAD [-9.] ; then compare it to the other end 4988 06673 7740 SMA SZA CLA ; ??? 4989 06674 5313 JMP DECNW2 ; still not a digit 4990 4991 ; Accumulate another decimal digit... 4992 06675 1065 TAD WORD ; get the old total 4993 06676 7104 CLL RAL ; multiply it by two 4994 06677 3065 DCA WORD ; and save that 4995 06700 1065 TAD WORD ; ... 4996 06701 7104 CLL RAL ; then multiply it by 4 more 4997 06702 7104 CLL RAL ; (for a total of 8) 4998 06703 1065 TAD WORD ; because 8x + 2x = 10x 4999 06704 1050 TAD SAVCHR ; then add the new digit 5000 06705 1373 TAD [-"0"] ; and correct for ASCII characters 5001 06706 3065 DCA WORD ; remember that for next time 5002 5003 ; Read the next digit and proceed... 5004 06707 2070 ISZ DIGITS ; remember one more digit processed 5005 06710 6205 .PUSHJ @ZGET ; get the next character 06711 5515 5006 06712 5267 JMP DECNW1 ; then keep trying 5007 5008 ; Here when we find something which isn't a digit... 5009 06713 7200 DECNW2: CLA ; ... 5010 06714 1070 TAD DIGITS ; get the digit count 5011 06715 7650 SNA CLA ; it has to be at least one 5012 06716 5525 JMP @ZCOMERR ; that's an error if it isn't 5013 06717 6225 .POPJ ; and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 122 Scan Octal Numbers BTS6120.PLX 5014 .TITLE Scan Octal Numbers 5015 5016 5017 ; This routine will read an octal number from the command line and return 5018 ; its value in location WORD. The value is usually limited to twelve bits, 5019 ; however any overflow bits will be left in location WORDH. This is intended 5020 ; for use by the OCTNF routine to extract the field from a 15 bit address. 5021 ; At least one octal digit must be found on the command line or COMERR will be 5022 ; called, and the first non-digit character found will be returned in location 5023 ; SAVCHR. 5024 06720 7200 OCTNW: CLA ; remove any junk 5025 06721 3065 DCA WORD ; clear the partial total 5026 06722 3070 DCA DIGITS ; we haven't read any digits yet 5027 06723 6205 .PUSHJ @ZSPACMP ; ignore any leading spaces 06724 5510 5028 5029 ; Check for an octal digit next... 5030 06725 1373 OCTN1: TAD [-"0"] ; compare it to a zero 5031 06726 7510 SPA ; ??? 5032 06727 5350 JMP OCTN2 ; this one isn't a digit 5033 06730 1371 TAD [-7] ; now compare to the high end of the range 5034 06731 7740 SMA SZA CLA ; ??? 5035 06732 5350 JMP OCTN2 ; still not a digit 5036 5037 ; Now accumulate another digit. 5038 06733 1065 TAD WORD ; get the previous total 5039 06734 3066 DCA WORDH ; and remember that for OCTNF 5040 06735 1065 TAD WORD ; then again 5041 06736 7006 RTL ; shift it left 3 bits 5042 06737 7004 RAL ; ... 5043 06740 0370 AND [7770] ; then insure that no junk has wrapped around 5044 06741 1050 TAD SAVCHR ; add the next digit 5045 06742 1373 TAD [-"0"] ; and correct for ASCII values 5046 06743 3065 DCA WORD ; remember the new total 5047 06744 2070 ISZ DIGITS ; also remember how many digits we read 5048 06745 6205 .PUSHJ @ZGET ; read the next character 06746 5515 5049 06747 5325 JMP OCTN1 ; then go look for more 5050 5051 ; Here when we find something which isn't a digit... 5052 06750 7200 OCTN2: CLA ; ... 5053 06751 1070 TAD DIGITS ; see how many digits we've read 5054 06752 7650 SNA CLA ; there must be at least one 5055 06753 5525 JMP @ZCOMERR ; nope -- this isn't legal 5056 06754 6225 .POPJ ; and return that in the AC 5057 06770 7770 06771 7771 06772 7767 06773 7720 06774 0133 06775 7746 06776 0101 06777 7677 5058 07000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 123 Scan 15 Bit Addresses BTS6120.PLX 5059 .TITLE Scan 15 Bit Addresses 5060 5061 5062 ; This routine will read a 15 bit address from the command. The lower 12 5063 ; bits of the address are always left in location WORD, and the upper 3 bits 5064 ; will be in location ADRFLD, properly justified. If the user types 5 or more 5065 ; digits in the octal address, the lower 12 bits becomes the address, and the 5066 ; next 3 most significant bits are the field. If his octal number has 4 or 5067 ; fewer digits, the field will be the current data field instead. For example, 5068 ; (assume that the current DF is 3): 5069 ; 5070 ; 1234 --> Location 1234, field 3 5071 ; 01234 --> Location 1234, field 0 5072 ; 41234 --> Location 1234, field 4 5073 ; 5641234 --> Location 1234, field 4 5074 ; 5075 ; Like the OCTNW routine, this routine will return the low order 12 bits 5076 ; in location WORD. There is an alternate entry point at location OCTNI; this 5077 ; is identical to OCTNF, except that the instruction field, not the data field, 5078 ; provides the default field number... 5079 5080 ; Here to read an address in the instruction field... 5081 07000 7200 OCTNI: CLA ; ... 5082 07001 1002 TAD UFLAGS ; use the instruction field as default 5083 07002 0131 AND ZK70 ; ... 5084 07003 5210 JMP OCTNF1 ; then proceed normally 5085 5086 ; Here to read an address in the data field... 5087 07004 7200 OCTNF: CLA ; ... 5088 07005 1002 TAD UFLAGS ; use the data field as the default 5089 07006 7014 R3L ; ... 5090 07007 0131 AND ZK70 ; ... 5091 07010 3036 OCTNF1: DCA ADRFLD ; and save the default for later 5092 07011 6205 .PUSHJ @ZOCTNW ; read a normal octal number 07012 5516 5093 07013 7200 CLA ; we don't care about this part 5094 07014 1070 TAD DIGITS ; see how many digits there were 5095 07015 1377 TAD [-5] ; we need at least 5 5096 07016 7710 SPA CLA ; ??? 5097 07017 6225 .POPJ ; there weren't that many -- use the default 5098 5099 ; Extract the upper 3 bits of the address... 5100 07020 1066 TAD WORDH ; get the high order bits 5101 07021 7002 BSW ; then put the upper 3 bits in the right place 5102 07022 0131 AND ZK70 ; trim it to just the important bits 5103 07023 3036 DCA ADRFLD ; then that is the new data field (temporarily) 5104 07024 6225 .POPJ ; that's all folks PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 124 Ask For Confirmation BTS6120.PLX 5105 .TITLE Ask For Confirmation 5106 5107 5108 ; This routine will type a question mark and then wait for the operator to 5109 ; enter a "Y" (or "y") to confirm. It's used by exceptionally dangerous 5110 ; commands, like FORMAT, and normally the caller will type a short string 5111 ; (e.g. "Format unit 0" before actually calling this function. If the 5112 ; operator does confirm, it will return with the link set. If the operator 5113 ; types anything other than "Y" or "y", it will return with the link clear. 5114 ; Note that it's also acceptable to just type Control-C to abort! 5115 07025 6205 CONFRM: .PUSHJ @[TQUEST] ; type a question mark 07026 5776 5116 07027 6205 CONF1: .PUSHJ @[INCHRS] ; go get a character of input 07030 5775 5117 07031 7450 SNA ; did we get anything ? 5118 07032 5227 JMP CONF1 ; nope - keep waiting 5119 07033 3050 DCA SAVCHR ; we got a real character - save it 5120 07034 1050 TAD SAVCHR ; and echo it back to the terminal 5121 07035 6205 .PUSHJ @ZOUTCHR ; ... 07036 5474 5122 07037 6205 .PUSHJ @ZCRLF ; followed by a CRLF 07040 5506 5123 5124 ; See what his answer was... 5125 07041 1050 TAD SAVCHR ; get the answer once more 5126 07042 1374 TAD [-"Y"] ; is it a "Y" 5127 07043 7450 SNA ; ??? 5128 07044 5252 JMP CONF2 ; yes - return with the link set 5129 07045 1373 TAD ["Y"-"y"] ; or a "y"? 5130 07046 7450 SNA ; ??? 5131 07047 5252 JMP CONF2 ; yes - same thing 5132 07050 7300 CLA CLL ; nope - return FALSE 5133 07051 6225 .POPJ 5134 5135 ; Here if he answered "Y" or "y"... 5136 07052 7320 CONF2: CLA STL ; return TRUE 5137 07053 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 125 Type Special Characters BTS6120.PLX 5138 .TITLE Type Special Characters 5139 5140 5141 ; This routine will simulate a TAB on the terminal, which it does by typing 5142 ; spaces until the horizontal position reaches a multiple of 8 characters. 5143 ; Note that this routine will always type at least one space. The AC is 5144 ; always cleared by this routine. 5145 07054 6205 TTABC: .PUSHJ TSPACE ; Always type at least one space 07055 5263 5146 07056 1053 TAD HPOS ; Get the current horizontal position 5147 07057 0132 AND ZK7 ; Is it a multiple of 8 ?? 5148 07060 7640 SZA CLA ; ??? 5149 07061 5254 JMP TTABC ; No -- keep typing 5150 07062 6225 .POPJ ; Yes -- we can stop now 5151 5152 ; This routine will type a space on the terminal. 5153 07063 7200 TSPACE: CLA ; Clear the AC 5154 07064 1372 TAD [" "] ; And load a space character 5155 07065 5771 JMP @[THCHAR] ; Then type it and return 5156 5157 ; This routine will type a question mark on the terminal. 5158 07066 7200 TQUEST: CLA ; ... 5159 07067 1370 TAD ["?"] ; ... 5160 07070 5771 JMP @[THCHAR] ; ... 5161 5162 ; This routine will type a BELL character on the terminal. 5163 07071 7200 TBELL: CLA ; ... 5164 07072 1367 TAD [CHBEL] ; Get a bell character 5165 07073 5766 JMP @[TFCHAR] ; Then type it out 5166 5167 ; Type a slash (used as an address separator) on the terminal. 5168 07074 7200 TSLASH: CLA ; ... 5169 07075 1365 TAD ["/"] ; ... 5170 07076 5771 JMP @[THCHAR] ; ... 5171 5172 ; Type a dot (used for decimal numbers and disk addresses) on the terminal. 5173 07077 7200 TDOT: CLA ; ... 5174 07100 1364 TAD ["."] ; ... 5175 07101 5771 JMP @[THCHAR] ; ... 5176 5177 ; Convert the value in the AC to a decimal digit and type it... 5178 07102 1363 TDIGIT: TAD ["0"] ; make it ASCII 5179 07103 5771 JMP @[THCHAR] ; type it and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 126 Type Carriage Return, Line Feed and Backspace BTS6120.PLX 5180 .TITLE Type Carriage Return, Line Feed and Backspace 5181 5182 5183 ; This routine will type a carriage return, line feed pair on the terminal 5184 ; and it will correctly update HPOS to show that the cursor is now at the left 5185 ; margin. In addition, it will keep count of the number of CRLFs output in 5186 ; location VPOS, and when the terminal's screen is full (as indicated by VPOS 5187 ; equals LENGTH) it will cause an automatic XOFF. The AC is always cleared 5188 ; on return. 5189 07104 7200 CRLF: CLA ; be sure the AC is cleared 5190 07105 1362 TAD [CHCRT] ; get a return character 5191 07106 6205 .PUSHJ @[TFCHAR] ; and type that out 07107 5766 5192 07110 3053 DCA HPOS ; remember that the cursor is in column zero 5193 5194 ; Now check the vertical position of the cursor... 5195 07111 2054 ISZ VPOS ; increment the current position 5196 07112 7000 NOP ; ... 5197 07113 1031 TAD LENGTH ; get the size of the screen 5198 07114 7450 SNA ; is it zero ?? 5199 07115 5327 JMP CRLF1 ; yes -- never stop 5200 07116 7041 CIA ; no -- make it negative 5201 07117 1054 TAD VPOS ; and compare it to the current location 5202 07120 7710 SPA CLA ; is the screen full ?? 5203 07121 5327 JMP CRLF1 ; no -- proceed 5204 07122 3054 DCA VPOS ; yes -- clear the vertical position 5205 07123 6205 .PUSHJ @[TBELL] ; type a bell character 07124 5761 5206 07125 7240 STA ; then load a -1 into the AC 5207 07126 3052 DCA XOFF ; and cause an automatic XOFF 5208 5209 ; Type the line feed next... 5210 07127 1360 CRLF1: TAD [CHLFD] ; now get a line feed 5211 07130 5766 JMP @[TFCHAR] ; type that and return 5212 5213 ; This routine will type a BACKSPACE character on the terminal and update 5214 ; HPOS to show the new cursor position. It will not allow you to backspace 5215 ; beyond the left margin of the temrinal. The AC is always cleared on return. 5216 07131 7240 TBACKS: STA ; load the AC with -1 5217 07132 1053 TAD HPOS ; and decrement HPOS 5218 07133 7510 SPA ; are we going to pass the left margin ?? 5219 07134 5341 JMP BACKS1 ; yes -- don't type anything 5220 07135 3053 DCA HPOS ; no -- update HPOS 5221 07136 1357 TAD [CHBSP] ; then get a backspace character 5222 07137 6205 .PUSHJ @[TFCHAR] ; and type that out 07140 5766 5223 07141 7200 BACKS1: CLA ; clear the AC 5224 07142 6225 .POPJ ; and that's all 5225 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 13-JAN-24 18:41:12 Page 127 Type Carriage Return, Line Feed and Backspace BTS6120.PLX 07177 7773 5226 07200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 128 Read Command Lines BTS6120.PLX 5227 .TITLE Read Command Lines 5228 5229 5230 ; This routine will read a single command line from the user and store the 5231 ; text of the line, one character per word and terminated by a null character, 5232 ; in the array at CMDBUF. The size of CMDBUF, and therefore the maximum 5233 ; length of a command, is given by MAXCMD and is normally a page (128 words). 5234 ; An auto-index register, L, is set aside just for the purpose of indexing the 5235 ; command buffer and when it returns this routine will always leave L set up 5236 ; to point to the beginning of the command. 5237 ; 5238 ; While it is reading the command, this routine will recognize these control 5239 ; characters: 5240 ; 5241 ; Control-C --> Abort the command 5242 ; Control-R --> Retype the current line, including corrections 5243 ; Control-U --> Erase the current line and start over again 5244 ; DELETE --> Erase the last character (echos the last character typed) 5245 ; BACKSPACE --> Erase the last character on a CRT 5246 ; Return --> Terminates the current command 5247 ; Line Feed --> " " " " 5248 ; ESCAPE --> " " " " 5249 ; 5250 ; When this routine is called, the AC should contain the prompting 5251 ; character. 5252 ; 5253 ; The calling sequence for INCHWL goes something like this: 5254 ; 5255 ; TAD ["x"] ; load the prompting character 5256 ; .PUSHJ @[INCHWL] ; and initialize the command scanner 5257 ; NXTCHR: .PUSHJ @[INCHW1] ; read and process the next character 5258 ; SNA CLA ; did we find the EOL? 5259 ; JMP NEXT ; no - keep processing 5260 ; 5261 ; 5262 ; The reason for this rather awkward sequence is that it allows the caller 5263 ; to add background processing to the character input loop (by inserting 5264 ; it at NXTCHR:). The main command scanner, for example, uses this to 5265 ; poll the front panel switches while we're waiting for input. 5266 5267 ; Call here first to initialize the scanner... 5268 07200 3141 INCHWL: DCA PROMPT ; remember the prompt character 5269 07201 1377 TAD [CMDBUF-1] ; point to the line buffer 5270 07202 3013 DCA L ; and initialize the pointer 5271 07203 3140 DCA CMDLEN ; say that this command is zero characters 5272 07204 3052 DCA XOFF ; clear the XOFF and 5273 07205 3051 DCA CTRLO ; control-O flags... 5274 07206 1141 TAD PROMPT ; get the prompting address back again 5275 07207 5474 JMP @ZOUTCHR ; type the prompt and return 5276 5277 ; Then call here to read and process the next character... 5278 07210 6205 INCHW1: .PUSHJ @[INCHRS] ; try to read something from the console 07211 5776 5279 07212 7450 SNA ; did we get anything ?? 5280 07213 6225 .POPJ ; no - return with the AC cleared 5281 07214 3050 DCA SAVCHR ; save this character for a while 5282 07215 3052 DCA XOFF ; then clear the XOFF, 5283 07216 3051 DCA CTRLO ; control-O, and 5284 07217 3054 DCA VPOS ; automatic XOFF flags 5285 07220 1050 TAD SAVCHR ; get the character back 5286 07221 1133 TAD ZMSPACE ; compare this to a space 5287 07222 7510 SPA ; ??? 5288 07223 5242 JMP INCHW3 ; this is a control character 5289 07224 1375 TAD [" "-177] ; is this a DELETE character ? 5290 07225 7650 SNA CLA ; ??? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 129 Read Command Lines BTS6120.PLX 5291 07226 5335 JMP INCHW8 ; yes -- go do that 5292 5293 ; Here to process a normal character... 5294 07227 1140 INCHW2: TAD CMDLEN ; get the length of this line 5295 07230 1374 TAD [-MAXCMD] ; and compare to the maximum 5296 07231 7700 SMA CLA ; are we already full ?? 5297 07232 5356 JMP INCH10 ; yes -- don't store this character 5298 07233 1050 TAD SAVCHR ; get the character back 5299 07234 6205 .PUSHJ @ZOUTCHR ; and echo it to the terminal 07235 5474 5300 07236 1050 TAD SAVCHR ; get the character again 5301 07237 3413 DCA @L ; store it in the line 5302 07240 2140 ISZ CMDLEN ; the command is one character longer now 5303 07241 5210 JMP INCHW1 ; and go get the next one 5304 5305 ; Here to handle a control-R command... 5306 07242 1373 INCHW3: TAD [" "-CHCTR] ; is this really a control-R ?? 5307 07243 7440 SZA ; ??? 5308 07244 5264 JMP INCHW4 ; no -- Proceed 5309 07245 3413 DCA @L ; yes -- close the command buffer 5310 07246 1372 TAD [CHCTR] ; get the control-R character back 5311 07247 6205 .PUSHJ @ZOUTCHR ; and echo that to the terminal 07250 5474 5312 07251 6205 .PUSHJ @ZCRLF ; start a new line 07252 5506 5313 07253 1141 TAD PROMPT ; get the prompt character first 5314 07254 6205 .PUSHJ @ZOUTCHR ; and always type that too 07255 5474 5315 07256 1377 TAD [CMDBUF-1] ; point to the current command 5316 07257 6205 .PUSHJ @[TASCIZ] ; and echo the entire line back 07260 5771 5317 07261 6205 .PUSHJ @ZBACKUP ; backup L over the null we put there 07262 5512 5318 07263 5210 JMP INCHW1 ; finally continue typing 5319 5320 ; Here to handle a Control-U character... 5321 07264 1370 INCHW4: TAD [CHCTR-CHCTU] ; is this really a Control-U character ?? 5322 07265 7440 SZA ; ??? 5323 07266 5275 JMP INCHW5 ; no -- keep trying 5324 07267 1367 TAD [CHCTU] ; yes -- get the character back again 5325 07270 6205 .PUSHJ @ZOUTCHR ; and echo that to the operator 07271 5474 5326 07272 6205 .PUSHJ @ZCRLF ; then start on a new line 07273 5506 5327 07274 5201 JMP INCHWL+1 ; and go start all over again 5328 5329 ; Here to handle a BACKSPACE character... 5330 07275 1366 INCHW5: TAD [CHCTU-CHBSP] ; is that what this is ?? 5331 07276 7440 SZA ; ??? 5332 07277 5312 JMP INCHW6 ; nope, not yet 5333 07300 1140 INCHBS: TAD CMDLEN ; yes -- get the length of this command 5334 07301 7650 SNA CLA ; is it a null line ?? 5335 07302 5210 JMP INCHW1 ; yes -- there's nothing to delete 5336 07303 6205 .PUSHJ @ZBACKS ; yes, type a backspace 07304 5476 5337 07305 6205 .PUSHJ @ZTSPACE ; then type a space 07306 5475 5338 07307 6205 .PUSHJ @ZBACKS ; and another backspace 07310 5476 5339 07311 5350 JMP INCHW9 ; finally join with the DELETE code 5340 5341 ; Here to check for line terminators... 5342 07312 1365 INCHW6: TAD [CHBSP-CHCRT] ; is this a return ?? 5343 07313 7450 SNA ; ??? 5344 07314 5326 JMP INCHW7 ; yes -- this line is done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 130 Read Command Lines BTS6120.PLX 5345 07315 1364 TAD [CHCRT-CHLFD] ; no -- Is it a line feed then ? 5346 07316 7450 SNA ; ??? 5347 07317 5326 JMP INCHW7 ; yes -- That's just as good 5348 07320 1363 TAD [CHLFD-CHESC] ; no -- How about an escape ? 5349 07321 7640 SZA CLA ; ??? 5350 07322 5227 JMP INCHW2 ; no -- just store this control character 5351 5352 ; Here to finish a command... 5353 07323 1362 TAD [CHESC] ; get the ESCAPE code back 5354 07324 6205 .PUSHJ @ZOUTCHR ; and echo that to the terminal 07325 5474 5355 07326 6205 INCHW7: .PUSHJ @ZCRLF ; then close the input line 07327 5506 5356 07330 3413 DCA @L ; end the command with a null byte 5357 07331 1377 TAD [CMDBUF-1] ; and then backup the pointer 5358 07332 3013 DCA L ; to the start of the command 5359 07333 7240 STA ; return with the AC non-zero 5360 07334 6225 .POPJ ; that's all there is to it 5361 5362 ; Here to process a DELETE character... 5363 07335 1032 INCHW8: TAD SCOPE ; is the scope flag set? 5364 07336 7640 SZA CLA 5365 07337 5300 JMP INCHBS ; yes - treat as a backspace 5366 07340 1140 TAD CMDLEN ; get the command length 5367 07341 7650 SNA CLA ; is this a null command ?? 5368 07342 5210 JMP INCHW1 ; yes -- there's nothing to delete 5369 07343 6205 .PUSHJ @ZBACKUP ; decrement the line pointer 07344 5512 5370 07345 1413 TAD @L ; get the last character stored 5371 07346 6205 .PUSHJ @ZOUTCHR ; and echo that for the DELETE 07347 5474 5372 5373 ; Now delete the last character typed... 5374 07350 6205 INCHW9: .PUSHJ @ZBACKUP ; decrement the line pointer 07351 5512 5375 07352 7240 STA ; then fix the command length too 5376 07353 1140 TAD CMDLEN ; ... 5377 07354 3140 DCA CMDLEN ; ... 5378 07355 5210 JMP INCHW1 ; finally go get the next character 5379 5380 ; Here if the command line is full -- echo a bell instead... 5381 07356 6205 INCH10: .PUSHJ @[TBELL] ; go type a bell character 07357 5761 5382 07360 5210 JMP INCHW1 ; then go wait for something to do 5383 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 5384 07400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 131 Terminal Output Primitives BTS6120.PLX 5385 .TITLE Terminal Output Primitives 5386 5387 5388 ; This routine will type the character in the AC on on the terminal. If the 5389 ; character is a printing character, it will be typed normally. If this 5390 ; character is happens to be a DELETE or NULL code (ASCII codes 00 and 7F), 5391 ; it will be ignored. If the character is a TAB, it is simulated by calling 5392 ; the TTABC routine. Finally, if it is any other control character, it is 5393 ; converted to the familiar ^x representation (unless it is an ESCAPE code, 5394 ; which, by tradition, is typed as $). This routine cannot be used to type 5395 ; carriage returns, line feeds, bells, or other control characters that are 5396 ; to be output literally. The AC is always cleared on return. 5397 07400 7450 OUTCHR: SNA ; first see if this character is a null 5398 07401 6225 .POPJ ; just drop it if it is 5399 07402 1133 TAD ZMSPACE ; see if this is a control character 5400 07403 7500 SMA ; skip if it is a control code 5401 07404 5226 JMP OUTCH3 ; just type a normal character 5402 5403 ; Here to type a TAB character... 5404 07405 1377 TAD [" "-CHTAB] ; is this really a TAB character at all ?? 5405 07406 7440 SZA ; ??? 5406 07407 5211 JMP OUTCH1 ; no -- check further 5407 07410 5776 JMP @[TTABC] ; yes -- type a TAB and return 5408 5409 ; Here to print an ESCAPE character... 5410 07411 1375 OUTCH1: TAD [CHTAB-CHESC] ; is this an ESCAPE character ?? 5411 07412 7440 SZA ; ??? 5412 07413 5216 JMP OUTCH2 ; no -- go type the ^x form instead 5413 07414 1374 TAD ["$"] ; yes -- type a dollar sign for an ESCAPE 5414 07415 5227 JMP THCHAR ; then type it and return 5415 5416 ; Here to print a control character... 5417 07416 6215 OUTCH2: .PUSH ; save the character for a while 5418 07417 7200 CLA ; and get the flag character 5419 07420 1373 TAD ["^"] ; ... 5420 07421 6205 .PUSHJ TFCHAR ; type that first 07422 5244 5421 07423 6235 .POP ; then get the character back 5422 07424 1372 TAD [CHESC+"@"] ; convert it to a printing character 5423 07425 5227 JMP THCHAR ; type that and return 5424 5425 ; Here to print a normal character... 5426 07426 1371 OUTCH3: TAD [" "] ; restore the original character 5427 ; and fall into THCHAR 5428 5429 5430 ; This routine will type a printing character and, while doing this, it will 5431 ; keep track of the horizontal position of the cursor. If it passes the line 5432 ; length of the terminal, a free carriage return is also typed. The terminal's 5433 ; horizontal position (HPOS) is also used for the tab simulation. The 5434 ; character to be typed should be in the AC, the AC will be cleared on return. 5435 07427 6215 THCHAR: .PUSH ; save the character for a while 5436 07430 2053 ISZ HPOS ; and incrment the horizontal position 5437 07431 7200 CLA ; get the maximum width allowed 5438 07432 1030 TAD WIDTH ; ... 5439 07433 7450 SNA ; is it zero ?? 5440 07434 5243 JMP THCHA1 ; yes -- no automatic carriage returns, then 5441 07435 7041 CMA CIA ; make it negative 5442 07436 1053 TAD HPOS ; and compare to the terminal cursor position 5443 07437 7710 SPA CLA ; have we reached the end of the line ?? 5444 07440 5243 JMP THCHA1 ; no -- proceed normally 5445 07441 6205 .PUSHJ @ZCRLF ; yes -- force a carriage return first 07442 5506 5446 07443 6235 THCHA1: .POP ; then get the character back 5447 ; and fall into TFCHAR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 132 Terminal Output Primitives BTS6120.PLX 5448 5449 5450 ; This routine will type a single character from the AC on the terminal. 5451 ; Before it types the character, this routine will check the state of the 5452 ; CNTRLO and XOFF flags. If a Control-O has been typed, the character is 5453 ; discarded and not typed on the terminal. If an XOFF has been typed, the 5454 ; output will be suspended until the user types an XON character (or a 5455 ; Control-O or Control-C). 5456 07444 6215 TFCHAR: .PUSH ; save the character for a while 5457 07445 6205 TFCHA1: .PUSHJ INCHRS ; check the operator for input 07446 5277 5458 07447 7200 CLA ; we don't care if anything was typed 5459 07450 1051 TAD CTRLO ; get the Control-O flag byte 5460 07451 7640 SZA CLA ; is it zero ?? 5461 07452 5260 JMP TFCHA2 ; no -- just throw this character away 5462 07453 1052 TAD XOFF ; now test the XOFF flag 5463 07454 7640 SZA CLA ; is the output suspended ?? 5464 07455 5245 JMP TFCHA1 ; wait for something to happen if we are XOFFed 5465 5466 ; Here when it is OK to type the character... 5467 07456 6235 .POP ; get the character back 5468 07457 5263 JMP CONOUT ; and send it to the UART 5469 5470 ; Here to return without typing anything... 5471 07460 6235 TFCHA2: .POP ; clean up the stack 5472 07461 7200 CLA ; but always return zero 5473 07462 6225 .POPJ ; and just quit 5474 5475 ; This routine will output a character from the AC to the terminal, with no 5476 ; no special processing of any kind. It simply waits for the console flag to 5477 ; set and then send the character. However, If the flag does not set in a 5478 ; reasonable amount of time then this routine will force the character out 5479 ; anyway. This prevents the monitor from hanging if the terminal flag is 5480 ; cleared by the user's program. 5481 ; 5482 ; The timeout loop requires 26 minor cycles which, with a 4.9152Mhz clock, 5483 ; takes 10.5 microseconds. If we simply clear the timeout counter when we 5484 ; start we'll get a timeout after 4096 counts, or about 43 milliseconds. 5485 ; If we assume that 300 baud is the slowest console we'll ever use, then 5486 ; that's just about right (at 300 baud a character takes about 33 milliseconds 5487 ; to transmit!). 5488 ; 5489 07463 3276 CONOUT: DCA CONCHR ; remember the character to send 5490 07464 3055 DCA IRMA ; and clear the timeout timer 5491 5492 ; See if the flag is set and send the character if so... 5493 07465 6041 CONOU1: TSF ; [9] is the flag set ??? 5494 07466 5273 JMP CONOU3 ; [4] no -- go check the timeout 5495 07467 1276 CONOU2: TAD CONCHR ; yes -- get the character 5496 07470 6046 TLS ; and send it to the console 5497 07471 7200 CLA ; a _real_ TLS doesn't clear the AC!! 5498 ;; .POPJ ; ... 5499 07472 5770 JMP @[UPDISP] ; keep the front panel display alive and exit 5500 5501 ; Here if the flag is not yet set... 5502 07473 2055 CONOU3: ISZ IRMA ; [9] have we waited long enough ??? 5503 07474 5265 JMP CONOU1 ; [4] no -- wait a little longer 5504 07475 5267 JMP CONOU2 ; yes -- force the character out anyway 5505 5506 ; Temporary storage for the CONOUT routine... 5507 07476 CONCHR: .BLOCK 1 ; a place to save the console character PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 133 Terminal Input Primitives BTS6120.PLX 5508 .TITLE Terminal Input Primitives 5509 5510 5511 ; This routine is called to check for operator input. It will test to see 5512 ; if the operator has typed a character. If he has not, this routine returns 5513 ; with the AC cleared and nothing else happens. If he has, this routine checks 5514 ; to see if the character is one of Control-C, Control-O, Control-S or 5515 ; Control-Q because these characters have special meaning and are acted upon 5516 ; immediately. If the input character is anything else, the character is 5517 ; returned in the AC. 5518 07477 6205 INCHRS: .PUSHJ @[UPDISP] ; keep the front panel display alive 07500 5770 5519 07501 6205 .PUSHJ CONIN ; try to read a character from the terminal 07502 5352 5520 07503 0130 AND ZK177 ; ignore the parity bit here 5521 07504 7450 SNA ; is this a null character ?? 5522 07505 6225 .POPJ ; yes -- just ignore it 5523 5524 ; Here process a control-C character -- restart the monitor... 5525 07506 1367 TAD [-CHCTC] ; is this really a control-C ?? 5526 07507 7440 SZA ; ??? 5527 07510 5317 JMP INCHR1 ; no -- proceed 5528 07511 3051 DCA CTRLO ; yes -- clear the control-O 5529 07512 3052 DCA XOFF ; and XOFF flags 5530 07513 1366 TAD [CHCTC] ; get another control-C character 5531 07514 6205 .PUSHJ @ZOUTCHR ; echo it to the terminal 07515 5474 5532 07516 5524 JMP @ZRESTA ; and go restart the monitor 5533 5534 ; Here to check for a control-O character... 5535 07517 1365 INCHR1: TAD [CHCTC-CHCTO] ; compare to a control-O character 5536 07520 7440 SZA ; is this it ?? 5537 07521 5334 JMP INCHR2 ; no -- keep checking 5538 07522 3052 DCA XOFF ; control-O always clears the XOFF flag 5539 07523 1364 TAD [CHCTO] ; get another control-O character 5540 07524 6205 .PUSHJ @ZOUTCHR ; and echo that 07525 5474 5541 07526 6205 .PUSHJ @ZCRLF ; then close the line 07527 5506 5542 07530 1051 TAD CTRLO ; get the current state of the control-O flag 5543 07531 7040 CMA ; and complement it 5544 07532 3051 DCA CTRLO ; that's the new value 5545 07533 6225 .POPJ ; return with the AC cleared 5546 5547 ; Here to check for a control-S character... 5548 07534 1363 INCHR2: TAD [CHCTO-CHXOF] ; is this a control-S ?? 5549 07535 7440 SZA ; ??? 5550 07536 5342 JMP INCHR3 ; nope, try again 5551 07537 7240 STA ; yes -- get a -1 into the AC 5552 07540 3052 DCA XOFF ; and set the XOFF flag 5553 07541 6225 .POPJ ; return with the AC cleared 5554 5555 ; Here to check for a control-Q character... 5556 07542 1362 INCHR3: TAD [CHXOF-CHXON] ; is this a control-Q ?? 5557 07543 7440 SZA ; ??? 5558 07544 5350 JMP INCHR4 ; no -- just give up 5559 07545 3052 DCA XOFF ; yes -- clear the XOFF flag 5560 07546 3054 DCA VPOS ; also clear the automatic XOFF counter 5561 07547 6225 .POPJ ; return with the AC cleared 5562 5563 ; Here if the character is nothing special... 5564 07550 1361 INCHR4: TAD [CHXON] ; restore the state of the AC 5565 07551 6225 .POPJ ; and return the character in the AC 5566 5567 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 134 Terminal Input Primitives BTS6120.PLX 5568 ; This routine will read a single character from the console UART. If no 5569 ; character is currently ready, it will return a null (zero) byte in the AC, 5570 ; but otherwise the character read is left in the AC... 5571 07552 7200 CONIN: CLA ; be sure the AC is cleared 5572 07553 6031 KSF ; is a character ready ?? 5573 07554 6225 .POPJ ; no -- just return zero 5574 07555 6036 KRB ; yes -- read it into the AC 5575 07556 6225 .POPJ ; then return that in the AC 5576 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 5577 07600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 135 Control Panel Entry Points BTS6120.PLX 5578 .TITLE Control Panel Entry Points 5579 5580 07600 .ORG 7600 5581 5582 ; There's a little bit of chicanery that goes on here (when have you seen 5583 ; a PDP-8 program without that???). After a power on clear or a hard reset, 5584 ; the HM6120 starts executing at location 7777 of panel memory which, in 5585 ; the case of the SBC6120, is part of the EPROM. The EPROM code at this 5586 ; location always jumps to the system initialization routine without even 5587 ; trying to figure out why we entered panel mode. 5588 ; 5589 ; The system initialization code copies all of the EPROM contents to panel 5590 ; RAM and then disables the EPROM forever. After that it actually changes 5591 ; the vector at location 7777 to point to the CPSAVE routine, which is the 5592 ; normal panel entry point for traps, halts, etc. 5593 7600 .VECTOR CPBOOT ; set the 6120 start up vector at 7777 5594 07600 6213 CPBOOT: CXF 1 ; the startup code lives in field 1 5595 07601 5776 JMP @[SYSINI] ; and away we go! 5596 5597 5598 ; Excluding a hardware reset, the 6120 will enter control panel mode for any 5599 ; of three other reasons: 5600 ; 5601 ; * any of the PR0..PR3 instructions were executed in main memory 5602 ; * the CPU was halted, either by a HLT instruction or by the RUN/HLT input 5603 ; * a panel interrupt was requested by the CPREQ pin 5604 ; 5605 ; In all the these cases, the 6120 was presumably executing some important 5606 ; program in main memory before it was interrupted, and we need to save the 5607 ; state of that program before doing anything else. When the 6120 enters 5608 ; panel mode it saves the last main memory PC in panel memory location 0 and 5609 ; then starts executing instructions in panel memory at 7777. The remainder of 5610 ; the main memory context (e.g. AC, MQ, flags, etc) we have to save manually. 5611 07602 3001 CPSAVE: DCA UAC ; save the AC 5612 07603 6256 GCF ; and the flags (including LINK, IF and DF) 5613 07604 3002 DCA UFLAGS ; ... 5614 07605 7501 MQA ; the MQ 5615 07606 3003 DCA UMQ ; ... 5616 07607 6207 RSP1 ; 6120 stack pointer #1 5617 07610 3004 DCA USP1 ; ... 5618 07611 6227 RSP2 ; " " " #2 5619 07612 3005 DCA USP2 ; .. 5620 5621 ; Now set up enough context so that this monitor can run. The CONT routine 5622 ; has saved in location STKSAV our last stack pointer before the main memory 5623 ; program was started and, if we're single stepping the main memory program, 5624 ; we're going to need that so that we can continue what we were doing. In 5625 ; the case of other traps the RESTA routine gets called which will reset the 5626 ; stack pointer. 5627 07613 1142 TAD STKSAV ; get the monitor's last known stack pointer 5628 07614 6217 LSP1 ; and restore that 5629 07615 6203 CXF 0 ; set both DF and IF to field zero 5630 07616 5775 JMP @[.+1] ; update the IF and clear the FZ flag 5631 07617 6276 SPD ; make indirect cycles access panel memory 5632 07620 3054 DCA VPOS ; reset the automatic XOFF line counter 5633 07621 6441 POST+1 ; show post code #1 5634 5635 ; Finally, we can determine the exact reason for entry into panel mode by 5636 ; reading the panel status flags with the PRS instruction, and that will tell 5637 ; us where to go next. Be careful, though, because executing PRS clears the 5638 ; flags so we only get to do it once! This code kind of assumes that only one 5639 ; of these flags can be set at any time - I believe that's true for the 6120. 5640 07622 6000 PRS ; get the reason for panel entry 5641 07623 7004 RAL ; BTSTRP -> LINK, PNLTRP -> AC0 5642 07624 7510 SPA ; test PNLTRP first PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 136 Control Panel Entry Points BTS6120.PLX 5643 07625 5253 JMP PNLTRP ; yes - a PRn instruction was trapped 5644 07626 7430 SZL ; next check BTSTRP 5645 07627 5236 JMP BTSTRP ; yes - an external CPREQ occurred 5646 07630 7004 RAL ; skip the next bit 5647 07631 7006 RTL ; put PWRON -> LINK, and HLTFLG -> AC0 5648 07632 7510 SPA ; test the HLTFLG bit 5649 07633 5311 JMP HALTED ; yes - a HLT instruction was trapped 5650 ; fall thru if PWRON (or none!) is set 5651 5652 ; If we get here, none of the known panel status bits are set. I don't 5653 ; know what this means, but it can't be good! We also jump here if the 5654 ; PWRON status bit is set. Since this bit can only be set by a hardware 5655 ; reset, and since in the SBC6120 this automatically maps EPROM instead 5656 ; of RAM, we should never see this happen. 5657 07634 4320 PWRON: JMS TRAP ; print a generic 5658 07635 3636 TRPMSG ; "% UNKNOWN TRAP AT ..." message 5659 5660 ; The BTSTRP flag indicates a transition of the CPREQ line, which could 5661 ; indicate that a break was typed on the console terminal, or it could 5662 ; indicate that the front panel (if one is installed) requires service. 5663 07636 BTSTRP: 5664 ; We get a CPREQ if the front panel HALT switch is flipped down (i.e. it 5665 ; makes the RUN -> HALT transition). We treat this case just as we would 5666 ; if a HLT instruction were executed - say "%HALTED AT ..." and start the 5667 ; BTS6120 command scanner. Note that if no front panel hardware is 5668 ; installed the SHSW IOT is a NOP and never skips! 5669 07636 6431 SHSW ; skip on halt switch transition 5670 07637 7410 SKP ; nope... 5671 07640 5311 JMP HALTED ; jump to the halt switch code 5672 ; The SCPT IOT will skip if the 30Hz front panel timer has ticked, which 5673 ; would mean that it's time to update the front panel display. Once again, 5674 ; remember that if no front panel is installed the SCPT IOT is a NOP and 5675 ; never skips, which is fine with us. 5676 07641 6433 SCPT ; skip on 30Hz timer 5677 07642 5246 JMP BTSTR1 ; nope - try something else 5678 07643 6205 .PUSHJ @[UPDISP] ; yes - update the display 07644 5774 5679 07645 5773 JMP @[CONT1] ; and then return to the main program 5680 5681 ; Here for an unknown CPREQ. This could be caused by a framing error 5682 ; (i.e. a BREAK) from the console terminal, or it could be caused by 5683 ; some other (optional) piece or hardware... 5684 07646 7000 BTSTR1: NOP ; patch space for a ROM patch 5685 07647 7000 NOP ; ... 5686 07650 7000 NOP ; ... 5687 07651 4320 JMS TRAP ; print 5688 07652 3602 BRKMSG ; "% BREAK AT ..." and restart 5689 5690 ; The PNLTRP flag indicates that one of the PR0 thru PR3 instructions has 5691 ; been executed, but unfortunately the only way to find out which is to 5692 ; use the last main memory PC to fetch the instruction from memory. Remember 5693 ; that the 6120 will have already incremented the PC by the time we get here, 5694 ; so it's actually one _more_ than the location we want. Currently the PR3 5695 ; instruction is used as a breakpoint trap and PR0 is a generic ROM "monitor 5696 ; call". The other two, PR1 and PR2, are unused. 5697 07653 7240 PNLTRP: STA ; decrement the PC 5698 07654 1000 TAD UPC ; so it points at the actual instruction 5699 07655 3000 DCA UPC ; that caused the trap 5700 07656 1002 TAD UFLAGS ; get the IF at the time of the trap 5701 07657 0131 AND ZK70 ; ... 5702 07660 1271 TAD PNLCDF ; make a CDF instruction out of that 5703 07661 3262 DCA .+1 ; and execute it 5704 07662 7000 NOP ; ... gets overwritten with a CDF ... 5705 07663 6266 CPD ; address main memory with indirect cycles 5706 07664 1000 TAD UPC PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 137 Control Panel Entry Points BTS6120.PLX 5707 07665 3006 DCA UIRPC 5708 07666 1400 TAD @UPC ; get the opcode that caused the trap 5709 07667 3007 DCA UIR ; and save it for later 5710 07670 6276 SPD ; back to panel memory 5711 07671 6201 PNLCDF: CDF 0 ; always field zero 5712 5713 ; See which instruction it was... 5714 07672 1007 TAD UIR ; get the opcode 5715 07673 1372 TAD [-BPT] ; is it PR3 ?? 5716 07674 7450 SNA ; ??? 5717 07675 5305 JMP BPTTRP ; yes - handle a break point trap 5718 07676 1371 TAD [BPT-PR0] ; no - is it PR0? 5719 07677 6213 CXF 1 ; (the ROM call handler lives in field 1) 5720 07700 7450 SNA ; ??? 5721 07701 5770 JMP @[MCALL] ; yes - handle a monitor call 5722 07702 6203 CXF 0 ; ... 5723 07703 4320 JMS TRAP ; for any others just print a generic 5724 07704 3612 PRNMSG ; "% PANEL TRAP AT ..." message 5725 5726 ; Here for a breakpoint trap... 5727 07705 4320 BPTTRP: JMS TRAP ; print 5728 07706 3545 BPTMSG ; "% BREAKPOINT AT ..." and proceed 5729 5730 ; Here (from field 1) for an illegal PR0 call... 5731 07707 4320 ILLPR0: JMS TRAP ; say 5732 07710 3560 PR0MSG ; "? ILLEGAL PR0 FUNCTION AT ..." 5733 5734 ; We get here when the 6120 halts, but unfortunately there are no less than 5735 ; three different reasons why it night have done this. The first is that the 5736 ; main memory program has executed a HLT (7402, or any microcoded combination 5737 ; there of) instruction. Or, it could be that the 6120 was halted externally 5738 ; by a transition on the HLTREQ input pin, however the SBC6120 has no hardware 5739 ; to do this. Lastly, it could be that the HALT flag was already set when 5740 ; we restarted the main memory program - in this case the 6120 will execute 5741 ; one instruction and trap back here. 5742 ; 5743 ; We use this situation intentionally to single step main memory programs, 5744 ; and we can tell when this happens by checking the SIMFLG flag in memory. 5745 ; This flag is normally cleared, but will be set by the SINGLE routine when we 5746 ; want to single step. In that case the monitor's stack is valid (it was 5747 ; saved to STKSAV by the CONT routine before switching context) and all we 5748 ; have to do is execute a .POPJ to return to the routine that originally 5749 ; called SINGLE. Keep your fingers crossed. 5750 07711 6435 HALTED: RLOF ; turn the RUN LED off 5751 07712 7200 CLA ; ... 5752 07713 1047 TAD SIMFLG ; did we execute a single instruction? 5753 07714 7640 SZA CLA ; ??? 5754 07715 6225 .POPJ ; yes - return from the SINGLE routine now! 5755 07716 4320 JMS TRAP ; otherwise just say 5756 07717 3625 HLTMSG ; "% HALTED AT ..." and restart 5757 5758 ; This routine does most of the generic work of handling traps to panel 5759 ; memory. It prints a message, which is passed inline via a JMS instruction, 5760 ; prints the PC, removes any breakpoints from the program and then restarts 5761 ; the monitor... 5762 07720 0000 TRAP: 0 ; call here with a JMS instruction 5763 07721 6435 RLOF ; turn the RUN LED off 5764 07722 6205 .PUSHJ @ZCRLF ; be sure we start on a new line 07723 5506 5765 07724 1720 TAD @TRAP ; get the address of the message 5766 07725 6205 .PUSHJ @[OUTSTR] ; and print that 07726 5767 5767 07727 1002 TAD UFLAGS ; then get the field of the trap 5768 07730 0131 AND ZK70 ; ... 5769 07731 6205 .PUSHJ @[TFIELD] ; and type that PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 138 Control Panel Entry Points BTS6120.PLX 07732 5766 5770 07733 1000 TAD UPC ; then the PC too 5771 07734 6205 .PUSHJ @ZTOCT4C ; type that and a CRLF 07735 5500 5772 07736 6205 .PUSHJ @[REGLSC] ; type the registers on the next line 07737 5765 5773 07740 6205 .PUSHJ @[BPTRMV] ; remove any breakpoints 07741 5764 5774 07742 6205 .PUSHJ @[EXMEM] ; sync the ADDRESS and DATA displays 07743 5763 5775 07744 5524 JMP @ZRESTA ; and restart the monitor 5776 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 5777 10200 .FIELD 1 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 139 Field 1 Variables BTS6120.PLX 5778 .TITLE Field 1 Variables 5779 5780 5781 ; This page defines all the page zero variables used by the code in field 5782 ; one. The system initialization code, part 1, at SYSINI: also lives in page 5783 ; zero of field one, and then is overwritten by these variables after init- 5784 ; ialization is completed. As a consequence, none of these variables can 5785 ; have initial values the way their field zero counter parts do! 5786 5787 10000 .ORG 0000 5788 5789 10000 F1X0: .BLOCK 1 5790 5791 ; Auto index registers... 5792 10010 .ORG 0010 5793 10010 RAMPTR: .BLOCK 1 ; address, within the RAM disk, for I/O 5794 10011 BUFPTR: .BLOCK 1 ; address of the caller's buffer for I/O 5795 10012 XX1: .BLOCK 1 ; generic auto index register for field 1 5796 10013 XX2: .BLOCK 1 ; " " " " " " 5797 10020 .ORG 0020 5798 5799 ; IDE Disk I/O routine storage... 5800 10020 DKPART: .BLOCK 1 ; 12 bit disk partition number 5801 10021 DKRBN: .BLOCK 1 ; 12 bit sector relative block number 5802 10022 DKSIZE: .BLOCK 1 ; size of attached drive, in MB, or 0 if no drive 5803 10023 DKUNIT: .BLOCK 1 ; logical unit (partition) number for OS/8 5804 5805 ; RAM Disk I/O routine storage... 5806 10024 RDUNIT: .BLOCK 1 ; currently selected RAM disk unit for I/O 5807 10025 RDPAGE: .BLOCK 1 ; " " " " " " page number 5808 10026 RAMBUF: .BLOCK 3 ; a three byte "mini buffer" for 3 <-> 2 packing 5809 10031 RAMDAR: .BLOCK 1 ; RAM disk address register (written to LDAR) 5810 10032 BATTOK: .BLOCK 1 ; -1 -> battery good, 1 -> battery bad, 0 -> unknown 5811 10033 RDSIZE: .BLOCK 10 ; size of each RAM disk unit, in KB, or 0 if none 5812 10043 RAMSIZ: .BLOCK 1 ; total size of all RAM disks, in KB 5813 10044 SIZPTR: .BLOCK 1 ; pointer to the RDSIZE array 5814 10045 RAMUSZ: .BLOCK 1 ; - size of selected RAM disk chip 5815 10046 RDTYPE: .BLOCK 1 ; 0 -> no RAM disk, -1 -> original (DS1221) RAM disk 5816 ; +1 -> new (DS1231) RAM disk, -2 -> IOB6120 RAM disk 5817 5818 ; ROM call arguments 5819 10047 MUUO: .BLOCK 1 ; ROM MCALL function code 5820 10050 ARGPTR: .BLOCK 1 ; pointer to MCALL (PR0) argument list 5821 10051 XFRCNT: .BLOCK 1 ; word count for I/O 5822 10052 BUFPNL: .BLOCK 1 ; -1 if the user buffer is in panel memory 5823 10053 BUFSIZ: .BLOCK 1 ; actual buffer size for RDIBUF/WRIBUF 5824 10054 RWCNT: .BLOCK 1 ; number of pages to be transferred 5825 5826 10200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 140 ROM Calls (PR0 Instructions) BTS6120.PLX 5827 .TITLE ROM Calls (PR0 Instructions) 5828 5829 10200 .ORG 0200 5830 5831 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 5832 ; HEX format) stores a checksum of ROM field 1 in location 10200. This is 5833 ; used by the POST and the VE (version) command. 5834 10200 ROMCK1: .BLOCK 1 5835 5836 ; This routine is called by CPSAVE when it detects a panel entry caused by 5837 ; a PR0 instruction. Main memory programs can use this instruction to 5838 ; communicate with the ROM firmware and, in particular, the OS/8 device driver 5839 ; for the RAM disk uses PR0 to transfer data. At this point all of the main 5840 ; memory program's registers have been saved and our original monitor stack 5841 ; has been restored. The data and instruction field are both one and the 5842 ; 6120 panel data flag is set (so indirect references go to panel memory). 5843 ; That's about all we can depend on. 5844 ; 5845 ; There are a couple of subtle points to watch out for here. One simple 5846 ; one is that, to save time, break points are not removed from the caller's 5847 ; program while we interpret a PR0. That means we have to be sure and return 5848 ; to main memory by jumping to CONT1, not CONT, since the latter will attempt 5849 ; to reinstall breakpoints _again_ and forever loose the original contents 5850 ; of those locations. 5851 ; 5852 ; The other thing to remember is that CONT and CPSAVE conspire to preserve 5853 ; the monitor's stack, so that it can return to the correct place while single 5854 ; stepping. That means we want to be sure and JMP to CONT1, not .PUSHJ to it, 5855 ; because otherwise it'll just return back to us the next time we enter panel 5856 ; mode! 5857 ; 5858 ; The convention is that the first word after PR0 is a function code to 5859 ; select the firmware routine. This routine also preserves the contents of 5860 ; the AC both ways - that is, whatever was in the user's AC when the PR0 was 5861 ; executed will be in the AC when our monitor call function is invoked, and 5862 ; whatever our monitor call function returns in the AC will be placed in the 5863 ; user's AC when control returns from the PR0. Anything more than that is up 5864 ; to the specific function invoked. 5865 5866 ; Get the first agument (the function code) and use it to determine the 5867 ; address of a ROM routine to handle it... 5868 10201 6205 MCALL: .PUSHJ GETARG ; CPSAVE leaves the PC pointing at the PR0 10202 5241 5869 ; so do a dummy GETARG to skip it 5870 10203 6205 .PUSHJ GETARG ; then get a real PR0 argument from main memory 10204 5241 5871 10205 3047 DCA MUUO ; this is always the function code 5872 10206 1047 TAD MUUO ; see if it's in range 5873 10207 7100 CLL ; be sure the link is in a known state 5874 10210 1377 TAD [-MAXFUN-1] ; check against the maximum function 5875 10211 7630 SZL CLA ; if it's legal, skip 5876 10212 5237 JMP MCALL2 ; nope - go print an error message... 5877 10213 1047 TAD MUUO ; it's legal - use it 5878 10214 1376 TAD [FUNTBL] ; index into the function dispatch table 5879 10215 3047 DCA MUUO ; ... 5880 10216 1447 TAD @MUUO ; get the address of the function routine 5881 10217 3047 DCA MUUO ; finally - that's what we wanted to know! 5882 5883 ; Invoke the monitor routine, preserving the AC in both directions. In 5884 ; addition, the LINK bit is commonly used as an error flag (i.e. the LINK 5885 ; set on return indicates an error), so it is preserved on return only. 5886 10220 6201 CDF 0 ; the user's context lives in field 0 5887 10221 1775 TAD @[UAC] ; get the user's AC 5888 10222 6211 CDF 1 ; all ROM call routines live in field 1 5889 10223 6205 .PUSHJ @MUUO ; call routine to execute the ROM call PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 141 ROM Calls (PR0 Instructions) BTS6120.PLX 10224 5447 5890 10225 6201 MCALL1: CDF 0 ; address the user's context again 5891 10226 3775 DCA @[UAC] ; return whatever's in the AC 5892 10227 7010 RAR ; put the link bit in AC0 5893 10230 3047 DCA MUUO ; save it for a minute 5894 10231 7350 NL3777 ; then mask off the LINK bit 5895 10232 0774 AND @[UFLAGS] ; in the user's flags 5896 10233 1047 TAD MUUO ; and put ours in there instead 5897 10234 3774 DCA @[UFLAGS] ; ... 5898 10235 6203 CXF 0 ; CONT2 lives in field 1 5899 10236 5773 JMP @[CONT2] ; and then return to main memory 5900 5901 ; Here when an illegal PR0 function is invoked. 5902 10237 6203 MCALL2: CXF 0 ; say 5903 10240 5772 JMP @[ILLPR0] ; "?Illegal PR0 function at ..." PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 142 Fetch PR0 Arguments BTS6120.PLX 5904 .TITLE Fetch PR0 Arguments 5905 5906 5907 ; This routine fetches an argument for PR0 from the main memory program. 5908 ; Since arguments are always stored in line after the PR0, the next argument 5909 ; is in the instruction field and pointed to by the last main memory PC. 5910 ; After the argument is fetched the main memory PC is always incremented so 5911 ; that we'll skip over the argument when we return - you have to be careful 5912 ; about this, since it means this routine can only be called ONCE to fetch 5913 ; any given argument! The PR0 argument is returned in the AC. 5914 10241 7200 GETARG: CLA 5915 10242 6201 CDF 0 ; BEWARE - UFLAGS and UPC are both in field 0! 5916 10243 1771 TAD @[UPC] ; get the user's PC from field 0 5917 10244 3050 DCA ARGPTR ; save it in field 1 for a moment 5918 10245 2771 ISZ @[UPC] ; and increment it to skip over the argument 5919 10246 7000 NOP ; this really shouldn't ever happen! 5920 10247 1774 TAD @[UFLAGS] ; get the last known user (main memory) flags 5921 10250 0370 AND [70] ; then get the IF at the time of the trap 5922 10251 1367 TAD [CDF 0] ; make a CDF instruction 5923 10252 3253 DCA .+1 ; change to the correct field 5924 10253 7000 NOP ; ... gets overwritten with a CDF ... 5925 10254 6266 CPD ; always fetch from main memory 5926 10255 1450 TAD @ARGPTR ; get the next word from user program space 5927 10256 6276 SPD ; back to panel memory 5928 10257 6211 CDF 1 ; and back to our field 5929 10260 6225 .POPJ ; return the PR0 argument in the AC PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 143 ROM Call Table BTS6120.PLX 5930 .TITLE ROM Call Table 5931 5932 5933 ; This is what you've really been waiting for - the table of ROM firmware 5934 ; function codes and routine addresses. 5935 5936 0237 BADFUN=MCALL2 ; illegal function call 5937 5938 10261 0302 FUNTBL: GETVER ; 0 - get ROM version 5939 10262 0307 RAMDRW ; 1 - read/write RAM disk 5940 10263 1000 GETRDS ; 2 - return RAM disk size 5941 10264 0600 GETBAT ; 3 - return RAM disk battery status 5942 10265 2017 DISKRW ; 4 - read/write IDE disk 5943 10266 1131 GETDKS ; 5 - return IDE disk size 5944 10267 1732 SETPMP ; 6 - set disk partition mapping 5945 10270 2000 GETPMP ; 7 - get disk partition mapping 5946 10271 2220 MEMMOV ; 10 - copy memory 5947 10272 2276 MEMMVX ; 11 - copy memory extended 5948 10273 2442 LIGHTS ; 12 - control the DATA LEDs 5949 5950 ; The following six locations are reserved for ROM calls added by the 5951 ; IOB6120 extension ROM. The first three are used by the GETCFS and R/STODC 5952 ; calls, and the remaining four are held for future expansion. If you add 5953 ; more ROM monitor calls the BTS6120, add them _after_ these six! 5954 10274 0237 BADFUN ; 13 - get CompactFlash card size 5955 10275 0237 BADFUN ; 14 - read Time of Day Clock (RTODC) 5956 10276 0237 BADFUN ; 15 - set Time of Day Clock (STODC) 5957 10277 0237 BADFUN ; 16 - (reserved for IOB6120) 5958 10300 0237 BADFUN ; 17 - (reserved for IOB6120) 5959 10301 0237 BADFUN ; 20 - (reserved for IOB6120) 5960 5961 ; Add new BTS6120 calls here... 5962 0020 MAXFUN=.-FUNTBL-1 5963 5964 5965 ; PR0 function zero returns the current firmware version in the AC... 5966 10302 7300 GETVER: CLA CLL ; ... 5967 10303 1366 TAD [VERSION] ; get our version number 5968 10304 6225 .POPJ ; MCALL will store it in the caller's AC 5969 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 144 Return from Routines in Field 1 BTS6120.PLX 5970 .TITLE Return from Routines in Field 1 5971 5972 5973 ; This routine is the other half of the code at PUSHJ1:, and it allows 5974 ; routines in field one which were called from field zero to return to 5975 ; field zero. It only needs to do two instructions, but those instructions 5976 ; have to be somewhere in field one! 5977 10305 6203 POPJ1: CXF 0 ; return to field zero 5978 10306 6225 .POPJ ; the address is already on the stack PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 145 RAM Disk support BTS6120.PLX 5979 .TITLE RAM Disk support 5980 5981 5982 ; The SBC6120 contains a DS1321 SRAM controller with Li battery backup and 5983 ; sockets for up to eight byte wide SRAM chips. Each socket can contain either 5984 ; a HM628512 512Kx8 SRAM or a HM628128 128Kx8 SRAM or, of course, nothing. 5985 ; Additionally, the last socket has two jumpers which permit a 512K byte 5986 ; CMOS EPROM to be used if desired. The maximum capacity of the RAM disk 5987 ; array is thus 2Mb - a pretty respectable sized disk (almost as big as a 5988 ; RK05J!) for OS/8. 5989 ; 5990 ; The SBC6120 maps these RAM chips into panel memory via the memory decode 5991 ; GAL and, when memory map 3 (MM3) is enabled, all indirect references to panel 5992 ; memory will access the RAM disk array. Since the RAM disk is only a byte 5993 ; wide, write operations discard the upper four bits of a twelve bit word, and 5994 ; when reading these bits are undefined and should be masked off by the 5995 ; software. 5996 ; 5997 ; Addressing the RAM disk is a little tricky, since a 2Mb memory requires 5998 ; a total of 21 address bits - quite a bit more than a PDP-8 can manage. 5999 ; RAM disk address bits 0..11 (the low order bits, contrary to the PDP-8 6000 ; convention) are supplied by the HM6120 MA11-0. The remaining 7 bits needed 6001 ; by each 512K SRAM come from a special register, the Disk Address Register, 6002 ; which can be loaded via the LDAR IOT. The final two bits needed by the 6003 ; DS1321 to select one of the four SRAM chips come from DF0 and DF1. 6004 ; 6005 ; DF2 is used as a "board select" to allow up to two SRAM boards to be 6006 ; installed. Since DF2 is actually the LSB of the data field, the board 6007 ; select is a little wierd - RAM disk units 0..3 are on the first RAM disk 6008 ; board and map to the even fields, 0, 2, 4 and 6. RAM disk units 4..7 are 6009 ; on the second RAM disk board and map to the odd fields - 1, 3, 5 and 7. 6010 ; 6011 ; Put more simply, the DF selects the SRAM chip used, the DAR selects the 6012 ; 4K byte "bank" within the chip, and the normal memory address selects the 6013 ; individual byte within the bank. 6014 ; 6015 ; For the purposes of writing an OS/8 device handler, each 4K RAM disk bank 6016 ; contains 21 pages of 128 twelve bit words, packed using the standard OS/8 6017 ; "three for two" scheme. A 512K SRAM chip can hold 128 of these banks, 6018 ; corresponding to DAR addresses 0..127, for a total capacity of 2688 PDP-8 6019 ; pages or 1344 OS/8 blocks. A 128K SRAM would contain only 32 banks, for a 6020 ; total of 672 PDP-8 pages or 336 OS/8 blocks. 6021 ; 6022 ; Sixty-four bytes are wasted in each bank by this packing scheme, which 6023 ; works out to about 21 OS/8 blocks lost in a 512K SRAM. More clever software 6024 ; could reclaim these, but it would require that the three-for-two packing 6025 ; algorithm split PDP-8 pages across RAM disk banks. 6026 ; 6027 ; The SRAMs are optional, and this SBC6120 may have all, only some, or even 6028 ; none installed. Since each SRAM chip is treated as a separate OS/8 unit, 6029 ; this makes it easy to handle the situation where some chips are not missing - 6030 ; these units are simply "off line". 6031 6032 ; RAM disk "geometry" constants... 6033 5200 RAM512=2688. ; size of a 512K RAM disk, in pages 6034 1240 RAM128=672. ; " " " 128K " " " " 6035 0025 BANKSZ=21. ; pages per bank of RAM disk memory 6036 6037 ; Special IOTs for the RAM disk hardware... 6038 6410 LDAR=6410 ; Load RAM disk address register 6039 6415 SBBLO=6415 ; Skip on backup battery low (DS1321 only!) PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 146 RAM Disk Read/Write ROM Call BTS6120.PLX 6040 .TITLE RAM Disk Read/Write ROM Call 6041 6042 6043 ; The calling sequence for the PR0 RAM disk R/W function is: 6044 ; 6045 ; PR0 6046 ; 0001 / panel function code for RAMDISK I/O 6047 ; / R/W bit, page count, buffer field and unit 6048 ; / buffer address 6049 ; / starting page number (not block number!) 6050 ; / AC == 0 if success; AC != 0 if error 6051 ; 6052 ; The error codes currently returned by RAMDRW are: 6053 ; 6054 ; 0001 - unit > 3 or SRAM chip not installed 6055 ; 0002 - page number > 2688 6056 ; 6057 ; If this looks a lot like an OS/8 handler call, that's no accident! 6058 10307 6205 RAMDRW: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 10310 5765 6059 10311 6205 .PUSHJ GETARG ; and lastly get the disk page number 10312 5241 6060 10313 3025 DCA RDPAGE ; ... 6061 6062 ; Select (after first ensuring that it exists!) the correct unit... 6063 10314 1047 TAD MUUO ; next get the unit number 6064 10315 0364 AND [7] ; ... 6065 10316 3024 DCA RDUNIT ; ... 6066 10317 6205 .PUSHJ @[RAMSEL] ; setup RAMCDF to select the correct "unit" 10320 5763 6067 10321 7630 SZL CLA ; was the unit number illegal ? 6068 10322 5762 JMP @[RAMER1] ; yes - give the error return 6069 6070 ; This loop reads or writes pages 'till we've done all we're supposed to... 6071 10323 6205 RDRW1: .PUSHJ @[SETDAR] ; calculate the RAM disk address and bank 10324 5761 6072 10325 7630 SZL CLA ; was the page number valid? 6073 10326 5760 JMP @[RAMER2] ; nope - give the bad page error return 6074 10327 1047 TAD MUUO ; get the function code again 6075 10330 7700 SMA CLA ; should we read (0) or write (1) ? 6076 10331 5335 JMP RDRW2 ; ... read 6077 10332 6205 .PUSHJ @[PACK] ; transfer a page from memory to RAM disk 10333 5757 6078 10334 5337 JMP RDRW3 ; and continue 6079 10335 6205 RDRW2: .PUSHJ @[UNPACK] ; transfer a page from RAM disk to memory 10336 5756 6080 10337 2025 RDRW3: ISZ RDPAGE ; if we need more, continue on the next page 6081 10340 2054 ISZ RWCNT ; have we done enough pages? 6082 10341 5323 JMP RDRW1 ; nope - keep going 6083 10342 7200 CLA ; all done with the RAMDRW call 6084 10343 6225 .POPJ ; return status code zero (no error) 6085 10356 0436 10357 0500 10360 0433 10361 0654 10362 0431 10363 0712 10364 0007 10365 2123 10366 0266 10367 6201 10370 0070 10371 0000 10372 7707 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 147 RAM Disk Read/Write ROM Call BTS6120.PLX 10373 2225 10374 0002 10375 0001 10376 0261 10377 7757 6086 10400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 148 RAM Disk Primary Bootstrap BTS6120.PLX 6087 .TITLE RAM Disk Primary Bootstrap 6088 6089 ; This routine will read page zero from RAM disk unit zero into page 6090 ; zero of field zero of main memory. The next step in the usual boot 6091 ; sequence would be to start the secondary bootstrap, but that's up to 6092 ; the caller... 6093 10400 7240 RDBOOT: STA ; point the buffer to page 0 6094 10401 3011 DCA BUFPTR ; ... 6095 10402 1377 TAD [CDF 0] ; of field zero 6096 10403 3776 DCA @[BUFCDF+1] ; ... 6097 10404 3052 DCA BUFPNL ; of main memory 6098 10405 3024 DCA RDUNIT ; read RAM disk unit zero 6099 10406 3025 DCA RDPAGE ; page zero 6100 ; JMP RAMDRD ; ... 6101 ; ** fall through into RAMDRD *** 6102 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 149 Read and Write RAM Disk Pages BTS6120.PLX 6103 .TITLE Read and Write RAM Disk Pages 6104 6105 6106 ; This routine will read a single page from RAM disk to a buffer in memory. 6107 ; The caller must set up RDUNIT and RDPAGE with the desired RAM disk unit 6108 ; and page, and BUFPTR, BUFCDF and BUFPNL with the address of a 128 word 6109 ; buffer in 6120 memory. If any errors are encountered, this routine will 6110 ; return with the LINK set and an error status in the AC. 6111 10407 6205 RAMDRD: .PUSHJ @[RAMSEL] ; select the unit in RDUNIT 10410 5775 6112 10411 7430 SZL ; was it invalid?? 6113 10412 5231 JMP RAMER1 ; yes - return error code 1 6114 10413 6205 .PUSHJ @[SETDAR] ; calculate the necessary disk address 10414 5774 6115 10415 7430 SZL ; is the page number invalid? 6116 10416 5233 JMP RAMER2 ; yes - return error code 2 6117 10417 5773 JMP @[UNPACK] ; unpack RAM disk data to the buffer and return 6118 6119 6120 ; This routine will write a single page from 6120 memory to RAM disk. Except 6121 ; for the direction of data flow, it's identical to RAMDRD, including all the 6122 ; parameters and error returns. 6123 10420 6205 RAMDWR: .PUSHJ @[RAMSEL] ; select the unit 10421 5775 6124 10422 7430 SZL ; was it invalid?? 6125 10423 5231 JMP RAMER1 ; yes - return error code 1 6126 10424 6205 .PUSHJ @[SETDAR] ; calculate the disk address 10425 5774 6127 10426 7430 SZL ; invalid page number?? 6128 10427 5233 JMP RAMER2 ; yes - return error code 2 6129 10430 5772 JMP @[PACK] ; pack buffer data into the RAM disk and return 6130 6131 6132 ; Here if the unit number is invalid... 6133 10431 7321 RAMER1: CLA CLL CML IAC ; return LINK = 1 and AC = 1 6134 10432 6225 .POPJ ; ... 6135 6136 ; Here if the page number is invalid... 6137 10433 7326 RAMER2: NL0002 ; return AC = 2 6138 10434 7120 STL ; and LINK = 1 6139 10435 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 150 Unpack RAM Disk Pages BTS6120.PLX 6140 .TITLE Unpack RAM Disk Pages 6141 6142 6143 ; This routine will read one page (aka a sector) of 128 PDP-8 words from 6144 ; the RAM disk to a buffer anywhere in main memory or panel memory. The 6145 ; address of the disk page read is selected by the RAMCDF and RAMPTR locations 6146 ; and the DAR register, which should be set up by prior calls to the RAMUNIT 6147 ; and SETDAR routines. The address of the buffer written is selected by the 6148 ; BUFPTR, BUFCDF and BUFPNL locations, which must be set up by the caller 6149 ; before invoking this routine. Exactly 128 words are always transferred, 6150 ; without fail! 6151 10436 7200 UNPACK: CLA ; ... 6152 10437 1371 TAD [-64.] ; one page is 128 words, or 64 word pairs 6153 10440 3051 DCA XFRCNT ; ... 6154 6155 ; Fetch the next three bytes (two words) from the SRAM chip. Note that 6156 ; the SRAMs are only eight bits wide, so we'll read indeterminate garbage for 6157 ; the upper four bits of each word. Those have to be masked off on the first 6158 ; two bytes, but for the third one it doesn't matter - it gets masked to two 6159 ; four bit pieces later anyway... 6160 10441 4770 UNPAC1: JMS @[RAMCDF] ; change the DF to the RAM disk unit 6161 10442 6403 MM3 ; and enable the RAM disk chips 6162 10443 1410 TAD @RAMPTR ; fetch three bytes from RAM disk 6163 10444 0367 AND [377] ; eight bits only, please 6164 10445 3026 DCA RAMBUF ; ... 6165 10446 1410 TAD @RAMPTR ; ... 6166 10447 0367 AND [377] ; ... 6167 10450 3027 DCA RAMBUF+1 ; ... 6168 10451 1410 TAD @RAMPTR ; ... 6169 10452 3030 DCA RAMBUF+2 ; ... 6170 10453 6402 MM2 ; restore the default memory map 6171 10454 6211 CDF 1 ; and field 6172 6173 ; Pack the three bytes into two words and store them in main/panel memory... 6174 10455 4766 JMS @[BUFCDF] ; change DF to the buffer field 6175 10456 1030 TAD RAMBUF+2 ; the upper 4 bits of the first word are here 6176 10457 7002 BSW ; shift them left six 6177 10460 7106 CLL RTL ; ... then eight bits 6178 10461 0365 AND [7400] ; and isolate just those four bits 6179 10462 1026 TAD RAMBUF ; assemble the first word 6180 10463 3411 DCA @BUFPTR ; and store it in main memory 6181 10464 1030 TAD RAMBUF+2 ; now do the upper 4 bits of the second word 6182 10465 7106 CLL RTL ; shift them left two 6183 10466 7106 CLL RTL ; ... then four bits 6184 10467 0365 AND [7400] ; and isolate just those four bits 6185 10470 1027 TAD RAMBUF+1 ; reassemble the second word 6186 10471 3411 DCA @BUFPTR ; store that in main memory too 6187 10472 6276 SPD ; return to panel memory 6188 10473 6211 CDF 1 ; and our own memory field 6189 10474 2051 ISZ XFRCNT ; have we done a full page? 6190 10475 5241 JMP UNPAC1 ; nope - keep copying 6191 10476 7100 CLL ; be sure the LINK is cleared for success 6192 10477 6225 .POPJ ; yes - we're outta here! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 151 Pack RAM Disk Pages BTS6120.PLX 6193 .TITLE Pack RAM Disk Pages 6194 6195 6196 ; This routine will write one page of 128 PDP-8 words from a buffer anywhere 6197 ; in either panel or main memory to RAM disk. It's the exact complement of 6198 ; UNPACK, and expects exactly the same things to be set up. 6199 10500 7200 PACK: CLA ; don't assume anything! 6200 10501 1371 TAD [-64.] ; do 64 word pairs, or 128 words 6201 10502 3051 DCA XFRCNT ; ... 6202 6203 ; Grab the next two twelve bit words from the buffer... 6204 10503 4766 PACK1: JMS @[BUFCDF] ; change DF to the buffer's field 6205 10504 1411 TAD @BUFPTR ; get a word from the buffer 6206 10505 3026 DCA RAMBUF ; save it for the computation of byte 3 6207 10506 1411 TAD @BUFPTR ; do the same with the second word 6208 10507 3027 DCA RAMBUF+1 ; ... 6209 10510 6276 SPD ; back to panel memory addressing 6210 6211 ; Store bytes 1 and 2 (they're easy) and calculate byte three. Note that 6212 ; the SRAM will ignore the upper four bits when writing (there's no hardware 6213 ; there!) so there's no need to worry about masking them out first... 6214 10511 4770 JMS @[RAMCDF] ; select the correct SRAM "unit" 6215 10512 6403 MM3 ; and enable the SRAM chips 6216 10513 1026 TAD RAMBUF ; store byte 1 6217 10514 3410 DCA @RAMPTR ; ... 6218 10515 1027 TAD RAMBUF+1 ; and byte 2 6219 10516 3410 DCA @RAMPTR ; ... 6220 10517 1026 TAD RAMBUF ; byte 3 has the top four bits of word 1 6221 10520 0365 AND [7400] ; ... 6222 10521 7002 BSW ; ... in bits 8..11 of the byte 6223 10522 7112 CLL RTR ; ... 6224 10523 3026 DCA RAMBUF ; save that for a moment 6225 10524 1027 TAD RAMBUF+1 ; and the top four bits of word 2 6226 10525 0365 AND [7400] ; ... 6227 10526 7112 CLL RTR ; in bits 4..7 6228 10527 7112 CLL RTR ; ... 6229 10530 1026 TAD RAMBUF ; ... 6230 10531 3410 DCA @RAMPTR ; ... 6231 10532 6402 MM2 ; return to the default memory map 6232 10533 6211 CDF 1 ; and field 6233 10534 2051 ISZ XFRCNT ; have we done a whole page? 6234 10535 5303 JMP PACK1 ; nope - keep going 6235 10536 7100 CLL ; be sure the LINK is cleared for success 6236 10537 6225 .POPJ ; all done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 152 Test DS1221 Batteries BTS6120.PLX 6237 .TITLE Test DS1221 Batteries 6238 6239 6240 ; This routine will test the status of the RAM disk backup batteries on the 6241 ; original, DS1221, RAM disk card. This routine will return incorrect, but 6242 ; harmless, information if the system really has the newer DS1231 RAM disk or 6243 ; the IOB6120 RAM disk, or no RAM disk at all. 6244 ; 6245 ; The DS1221 doesn't have a status bit to give us the battery state directly, 6246 ; but it does have a clever hack to allow us to infer what we want to know. If 6247 ; the batteries have failed, then the DS1221 will inhibit all chip select 6248 ; outputs on the _second_ memory cycle (but not the first!). We can use this 6249 ; by 1) reading any location and saving its value, 2) writing any different 6250 ; value to the same location, and 3) reading it back again. If the batteries 6251 ; are dead, the second cycle will be inhibited, and the value read in step 3 6252 ; will be the same as 1. Of course, this presupposes that there's functional 6253 ; memory installed in the first place, if there isn't then this algorithm will 6254 ; erroneously report that the batteries are dead. 6255 ; 6256 ; Because of the way this works, this routine has to be called before ANY 6257 ; other access is made to MM3, including the extension ROM initialization. 6258 ; That's why the DS1221 battery test is in a routine all by itself - the 6259 ; battery test for the other two styles (DS1231 and IOB6120) is done by the 6260 ; RDCHK1 routine. 6261 ; 6262 10540 0000 CK1221: 0 6263 10541 1364 TAD [32.] ; test bank 32 to avoid A17 problem 6264 10542 6410 LDAR ; select the RAM bank for testing 6265 10543 6403 MM3 ; enable RAM disk access 6266 10544 6201 CDF 0 ; use 1st RAMdisk RAM for test 6267 10545 1763 TAD @[7777] ; (1) read the last byte of this bank 6268 10546 7421 MQL ; save it for a minute 6269 10547 7701 ACL ; .... 6270 10550 7041 CIA ; make it negative 6271 10551 3763 DCA @[7777] ; (2) and write it back 6272 10552 7701 ACL ; get the original data 6273 10553 1763 TAD @[7777] ; (3) add what should be the complement 6274 10554 0367 AND [377] ; ignore all but the bottom eight bits 6275 10555 7650 SNA CLA ; if it's not zero then the second cycle was 6276 10556 7344 NLM2 ; ... inhibited because the batteries are dead 6277 10557 7001 IAC ; AC=-1 if battery good, AC=+1 if battery bad 6278 10560 3032 DCA BATTOK ; ..... 6279 ; CDF 1 ; back to current field 6280 10561 6402 MM2 ; back to the default memory map 6281 10562 5740 JMP @CK1221 ; ... 6282 10563 7777 10564 0040 10565 7400 10566 2211 10567 0377 10570 0743 10571 7700 10572 0500 10573 0436 10574 0654 10575 0712 10576 2212 10577 6201 6283 10600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 153 Get Battery Status ROM Call BTS6120.PLX 6284 .TITLE Get Battery Status ROM Call 6285 6286 6287 ; The Get Battery Status ROM call will return the status of the RAM disk 6288 ; lithium backup batteries. As long as either battery has sufficient 6289 ; voltage, -1 will be return in the AC. If both batteries have failed, then 6290 ; zero is returned. 6291 ; 6292 ; PR0 / call the SBC6120 ROM firmware 6293 ; 0003 / get backup battery status function code 6294 ; / return with AC == -1 if batteries are OK 6295 ; / AC == +1 if batteries are bad 6296 ; / AC == 0 if battery status unknown 6297 ; 6298 ; NOTE: Because of the way the DS1221 works, the battery status can only 6299 ; be tested after power up. It isn't possible to monitor the battery status 6300 ; in real time! 6301 10600 7300 GETBAT: CLA CLL ; ... 6302 10601 1032 TAD BATTOK ; return the battery status in the AC 6303 10602 6225 .POPJ ; and that's it PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 154 Determine RAM Disk Model BTS6120.PLX 6304 .TITLE Determine RAM Disk Model 6305 6306 ; This routine will determine the type of the RAM disk installed and sets 6307 ; the RDTYPE variable accordingly: 6308 ; 6309 ; -2 -> IOB6120 RAM disk 6310 ; -1 -> original (DS1221) RAM disk 6311 ; 0 -> no RAM disk 6312 ; +1 -> new (DS1231) RAM disk 6313 ; 6314 ; Each of these implementations has slightly different characteristics (sigh!) 6315 ; and so it's important to know which one we've got. Note that this routine 6316 ; is called only once, during phase 2 of system initialization. 6317 10603 7200 RDCHK1: CLA 6318 ; If the IOB6120 is in use, then we've obviously got the IOB6120 style 6319 ; RAM disk. Also, since the IOB6120 doesn't support any low battery detection 6320 ; for the RAM disk backup battery, we'll take this chance to set BATTOK to 6321 ; zero (unknown battery status). 6322 10604 6201 CDF 0 ; the EXTFLAG lives in field 0 6323 10605 1777 TAD @[EXTFLAG] ; get the IOB6120 status 6324 10606 6211 CDF 1 ; ... 6325 10607 7650 SNA CLA ; is there one? 6326 10610 5214 JMP RDCH10 ; no - go check for a DS1221 RAMdisk card 6327 10611 3032 DCA BATTOK ; yes - set the battery status to unknown 6328 10612 7344 NLM2 ; and set RDTYPE to -2 (IOB6120 RAM disk) 6329 10613 5251 JMP RDCH12 ; .... 6330 6331 ; The original RAMdisk card (the one with the DS1221 chip) didn't decode 6332 ; EMA2 and so the even and odd fields select the same SRAM chip. This code 6333 ; does a very simple test to detect that case (remember that we aren't even 6334 ; sure _any_ RAMdisk exists at this point!) and sets the maximum unit to 4 6335 ; if it detects this duplication. Note that this assumes that if any 6336 ; RAMdisk chip is installed, the first one is! 6337 10614 1376 RDCH10: TAD [32.] ; test bank 32 so A17 will be set 6338 10615 6410 LDAR ; ... 6339 10616 6403 MM3 ; address the RAMdisk map 6340 10617 6201 CDF 0 ; select the first chip 6341 10620 1375 TAD [252] ; put a test pattern in one location 6342 10621 3774 DCA @[7776] ; ... 6343 10622 1373 TAD [125] ; and a different one in the next 6344 10623 3772 DCA @[7777] ; ... 6345 10624 1774 TAD @[7776] ; add them up 6346 10625 1772 TAD @[7777] ; ... 6347 10626 7040 CMA ; the result should be 377 6348 10627 0371 AND [377] ; remember that only 8 bits exist 6349 10630 7640 SZA CLA ; skip if any RAM disk exists? 6350 10631 5251 JMP RDCH12 ; none - set RDTYPE to zero and exit 6351 10632 6211 CDF 1 ; address an odd numbered chip 6352 10633 3774 DCA @[7776] ; clear this location in chip #1 6353 10634 6201 CDF 0 ; read the original chip again 6354 10635 1774 TAD @[7776] ; ... 6355 10636 0371 AND [377] ; the RAMdisk array is only 8 bits 6356 10637 1370 TAD [-252] ; if this is now zero 6357 10640 7650 SNA CLA ; ... we can be pretty sure it's an old card 6358 10641 5244 JMP RDCH11 ; nope - modern DS1231 card 6359 6360 ; Here for the old stype (DS1221) card... 6361 10642 7240 NLM1 ; set RDTYPE to -1 6362 10643 5251 JMP RDCH12 ; store it and return... 6363 6364 ; Here for a modern (DS1231) card... 6365 10644 7201 RDCH11: NL0001 ; set the AC to +1 6366 10645 6415 SBBLO ; skip of the DS1231 battery is low 6367 10646 7240 NLM1 ; not low - set BATTOK to -1 6368 10647 3032 DCA BATTOK ; update the battery status flag PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 155 Determine RAM Disk Model BTS6120.PLX 6369 10650 7201 NL0001 ; and finally set RDTYPE to 1 6370 10651 3046 RDCH12: DCA RDTYPE ; ... 6371 10652 6402 MM2 ; return to the normal memory map 6372 10653 6225 .POPJ ; and we're all done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 156 Calculate RAM Disk Addresses BTS6120.PLX 6373 .TITLE Calculate RAM Disk Addresses 6374 6375 6376 ; This routine will calculate the RAM disk bank number and the relative 6377 ; offset within that bank, corresponding to a disk page number passed in 6378 ; location DKPAGE. The resulting bank number is simply loaded directly into 6379 ; the DAR via the LDAR IOT, and the offset is left in auto index location 6380 ; RAMPTR, where it can be used by the UNPACK and PACK routines. If the page 6381 ; number passed is illegal (i.e. greater than the size of the selected RAM 6382 ; disk unit) then the link will be set when this routine returns. 6383 10654 7300 SETDAR: CLA CLL ; make sure the link is in a known state 6384 10655 1025 TAD RDPAGE ; get the desired page 6385 10656 1045 TAD RAMUSZ ; compare it to the size of this unit 6386 10657 7630 SZL CLA ; is the page number legal? 6387 10660 6225 .POPJ ; no - return with the LINK set 6388 6389 ; Divide the page number by 21, the number of pages per bank, by repeated 6390 ; subtraction. This is kind of crude, but it only has to iterate 127 times, 6391 ; worst case, so the performance hit isn't that bad. We do have to be careful, 6392 ; though, because the largest legal page number is 2688, which is bigger than 6393 ; 2048. That means we have to treat the whole AC as a 12 bit UNSIGNED value! 6394 10661 3031 DCA RAMDAR ; clear the disk address (quotient) 6395 10662 1025 TAD RDPAGE ; get the selected RAM disk page number 6396 10663 7100 SETDA1: CLL ; make sure the link is clear before starting 6397 10664 1367 TAD [-BANKSZ] ; try to subtract another 21 6398 10665 7420 SNL ; did it fit? 6399 10666 5271 JMP SETDA2 ; nope - we can stop now 6400 10667 2031 ISZ RAMDAR ; yes - increment the disk address 6401 10670 5263 JMP SETDA1 ; and keep subtracting 6402 6403 ; We get here when we're done dividing, with the quotient in RAMDAR and the 6404 ; remainder in the AC. To calculate the byte offset within a bank, we need 6405 ; to multiply the remainder by 192 (the number of bytes per 128 word page). 6406 10671 1366 SETDA2: TAD [BANKSZ] ; restore the remainder 6407 10672 7002 BSW ; then multiply by 64 6408 10673 3010 DCA RAMPTR ; save offset*64 for a moment 6409 10674 1010 TAD RAMPTR ; ... 6410 10675 7104 CLL RAL ; then multiply by two again 6411 10676 1010 TAD RAMPTR ; 192*x = 128*x + 64*x 6412 10677 6201 CDF 0 ; adjust by base offset, default 0 - 1 6413 10700 1765 TAD @[RAMBAS] ; (auto index registers pre-increment) 6414 10701 6211 CDF 1 6415 10702 3010 DCA RAMPTR ; that's the final offset 6416 6417 ; Set up the DAR with the bank number, from RAMDAR. Remember that for the 6418 ; 128K chips, we must always set A17 to enable the alternate chip select! 6419 10703 1045 TAD RAMUSZ ; get the size of the selected unit 6420 10704 1364 TAD [RAM128] ; ... 6421 10705 7650 SNA CLA ; is this a 128K ram chip ? 6422 10706 1376 TAD [32.] ; yes - always set A17 6423 10707 1031 TAD RAMDAR ; get the quotient from the division 6424 10710 6410 LDAR ; and load the disk address register 6425 10711 6225 .POPJ ; and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 157 Select RAM Disk Unit BTS6120.PLX 6426 .TITLE Select RAM Disk Unit 6427 6428 6429 ; This routine will set up the RAMCDF routine to select the desired RAM 6430 ; disk "unit". The unit number, 0..7, should be passed in RDUNIT. If the 6431 ; unit number given is illegal (i.e. greater than seven) OR if there is no 6432 ; SRAM chip installed in the selected position, this routine will return 6433 ; with the link set. 6434 10712 7300 RAMSEL: CLL CLA ; make sure the link is in a known state 6435 10713 1024 TAD RDUNIT ; get the desired unit number 6436 10714 1363 TAD [-10] ; see if the unit is legal 6437 10715 7630 SZL CLA ; it must be less than 8 6438 10716 6225 .POPJ ; no - return with the link set 6439 ; The mapping of RAMdisk units to data fields is a little obscure - units 6440 ; 0..3 map to fields 0, 2, 4, and 6 (i.e. the even fields). RAMdisk units 6441 ; 4..7 map to the odd fields (1, 3, 5, 7)... 6442 10717 1024 TAD RDUNIT ; restore the original unit 6443 10720 7104 CLL RAL ; shift the unit number left once 6444 10721 1363 TAD [7770] ; if the unit is 4..7 then set the link 6445 10722 7430 SZL ; skip if the unit is 0..3 6446 10723 7001 IAC ; make the field odd for units 4..7 6447 10724 7114 CLL R3L ; and position it for a CDF instruction 6448 10725 0362 AND [70] ; ... 6449 10726 1361 TAD [CDF 0] ; make a CDF to the corresponding field 6450 10727 3344 DCA RAMCDF+1 ; and store that in the unit select routine 6451 6452 ; Now that we know the unit number is valid, verify that this chip is really 6453 ; installed by checking the RDSIZE array for a non-zero value. As a side 6454 ; effect of this, we always leave the size of the currently selected unit in 6455 ; location RAMUSZ, where it's used by SETDAR to determine whether the page 6456 ; addressed is actually legal. We always want to update RAMUSZ, even if the 6457 ; chip is not installed, because this will also cause SETDAR to fail if the 6458 ; caller ignores the our error return and attempts a read or write anyway. 6459 10730 1024 TAD RDUNIT ; get the unit number again 6460 10731 1377 TAD [RDSIZE] ; index into the RDSIZE array 6461 10732 3044 DCA SIZPTR ; ... 6462 10733 1444 TAD @SIZPTR ; to get the size of this chip 6463 10734 7041 CIA ; make it negative 6464 10735 3045 DCA RAMUSZ ; and save that for SETDAR 6465 10736 1045 TAD RAMUSZ ; ... 6466 10737 7100 CLL ; make sure the link is in a known state 6467 10740 7650 SNA CLA ; is this chip installed ? 6468 10741 7020 CML ; nope - give the error return 6469 10742 6225 .POPJ ; ... 6470 6471 ; This little routine can be called, via a JMS instruction (not a .PUSHJ!) 6472 ; to change the DF and select the last RAM disk unit set by a call to RAMSEL. 6473 10743 0000 RAMCDF: 0 ; call here via a JMS! 6474 10744 7000 NOP ; gets overwritten with a CDF instruction 6475 10745 5743 JMP @RAMCDF ; return... 6476 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 13-JAN-24 18:41:12 Page 158 Select RAM Disk Unit BTS6120.PLX 10777 0033 6477 11000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 159 Get RAM Disk Size ROM Call BTS6120.PLX 6478 .TITLE Get RAM Disk Size ROM Call 6479 6480 6481 ; PR0 function 2 will return the size of a RAM disk chip, in 128 word pages, 6482 ; in the AC. The AC should be loaded with the desired unit number, 0..7, 6483 ; before invoking PD0. If no chip is installed in the selected unit, zero 6484 ; will be returned in the AC. If the unit number is not in the range 0..7, 6485 ; then on return the LINK will be set to indicate an error. 6486 ; 6487 ; For example: 6488 ; TAD (unit / load the desired RAM disk unit, 0..7 6489 ; PR0 / call the ROM software 6490 ; 0002 / function code for Get RAM Disk Status 6491 ; / return the RAM disk size in the AC 6492 6493 ; It's tempting to use the RAMSEL routine here to save some steps, but be 6494 ; careful - RAMSEL will return with the LINK set (an error condition) if a 6495 ; valid unit number is selected but there is no SRAM chip installed there. 6496 ; That's not what we want for this ROM call, which should return an error only 6497 ; if the selected unit is > 7! 6498 11000 3024 GETRDS: DCA RDUNIT ; save the unit number 6499 11001 1024 TAD RDUNIT ; and get it back 6500 11002 7100 CLL ; be sure the link is in a known state 6501 11003 1377 TAD [-10] ; is it a legal unit number ? 6502 11004 7630 SZL CLA ; skip if so 6503 11005 6225 .POPJ ; no - return with the LINK set and AC clear 6504 11006 1024 TAD RDUNIT ; one more time 6505 11007 1376 TAD [RDSIZE] ; index the RDSIZE array 6506 11010 3044 DCA SIZPTR ; ... 6507 11011 1444 TAD @SIZPTR ; get the size of this disk 6508 11012 6225 .POPJ ; and return it with the LINK cleared PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 160 ATA Disk Support BTS6120.PLX 6509 .TITLE ATA Disk Support 6510 6511 6512 ; BTS6120 supports any standard ATA hard disk connected to the SBC6120 IDE 6513 ; interface. Nearly all hard disks with IDE interfaces are ATA; conversely, 6514 ; nearly all non-hard disk devices (e.g. CDROMs, ZIP drives, LS-120s, etc) 6515 ; with IDE interfaces are actually ATAPI and not ATA. ATAPI requires a 6516 ; completely different protocol, which BTS6120 does not support, and BTS6120 6517 ; will simply ignore any ATAPI devices connected to the IDE interface. 6518 ; BTS6120 supports only a single physical drive, which must be set up as the 6519 ; IDE master, and any IDE slave device will be ignored. 6520 ; 6521 ; Since BTS6120 does not support cylinder/head/sector (C/H/S) addressing, 6522 ; the hard disk used must support logical block addressing (LBA) instead. 6523 ; All modern IDE/ATA drives support LBA, as do most drives manufactured in the 6524 ; last five or six years, however some very old drives may not. If BTS6120 6525 ; detects an ATA drive that does not support LBA it will display the message 6526 ; "IDE: Not supported" during startup and there after ignore the drive. 6527 ; 6528 ; All IDE devices, regardless of vintage, transfer data in sixteen bit words 6529 ; and each sector on an ATA disk contains 512 bytes, or 256 sixteen bit words. 6530 ; When writing to the disk, BTS6120 converts twelve bit PDP-8 words to sixteen 6531 ; bits by adding four extra zero bits to the left and, when reading from the 6532 ; disk, BTS6120 converts sixteen bit words to twelve bits by simply discarding 6533 ; the most significant four bits. No packing is done. This conveniently 6534 ; means that each ATA sector holds 256 PDP-8 words, or exactly one OS/8 block. 6535 ; It also means that one quarter of the disk space is wasted, in this era of 6536 ; multi-gigabyte disks that hardly seems like an issue. 6537 ; 6538 ; OS/8 handlers and the OS/8 file system use a single twelve bit word to hold 6539 ; block numbers, which means that OS/8 mass storage devices are limited to a 6540 ; maximum of 4096 blocks . Using the BTS6120 non-packing scheme for storing 6541 ; data, 4096 PDP-8 blocks are exactly 2Mb. Clearly, if a single OS/8 device 6542 ; corresponds to an entire hard disk then nearly all of the disk space would 6543 ; be wasted. The normal solution is to partition the hard disk into many OS/8 6544 ; units, with each unit representing only a part of the entire disk. Since 6545 ; OS/8 cannot support a single unit larger than 2Mb there isn't any point in 6546 ; allowing partitions to be larger than that, and since the smallest drives 6547 ; available today can hold hundreds if not thousands of 2Mb partitions, there 6548 ; isn't much point in allowing a partition to be smaller than that, either. 6549 ; 6550 ; Because of this, BTS6120 supports only fixed size partitions of 2Mb each. 6551 ; This greatly simplifies the software since a twenty four bit disk sector 6552 ; number can now be calculated simply by concatenating a twelve bit partition 6553 ; number with the twelve bit OS/8 relative block number (RBN). No "super 6554 ; block" with a partition table is needed to keep track of the sizes and 6555 ; positions of each partition, and the OS/8 handler is simplified since each 6556 ; disk partition is always the same size. A twenty four bit sector address 6557 ; permits disks of up to 8Gb to be fully used, which seems more than enough 6558 ; for a PDP-8. 6559 ; 6560 ; Once again, in BTS6120 the partition number simply refers to the most 6561 ; significant twelve bits of a twenty-four bit disk address, and the OS/8 6562 ; block number is the least significant twelve bits. It's no more complicated 6563 ; than that! 6564 ; 6565 ; The ID01 is the OS/8 handler for the SBC6120 IDE/ATA disk. It supports 6566 ; eight units, IDA0 through IDA7, in a single page and may be assembled as 6567 ; either a system (IDSY) or non-system (IDNS) handler. The system handler 6568 ; version of the ID01 contains a secondary bootstrap that can be booted by 6569 ; the BTS6120 Boot command. The ID01 is a simple handler that uses HD-6120 6570 ; PR0 instruction to invoke BTS6120 functions for low level IDE disk access 6571 ; and data transfer. 6572 ; 6573 ; BTS6120 implements a partition map which defines the partition number PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 161 ATA Disk Support BTS6120.PLX 6574 ; corresponding to each OS/8 ID01 unit, and when an OS/8 program accesses an 6575 ; ID01 unit BTS6120 uses this table to determine the upper twelve bits of the 6576 ; LBA. At power on or after a MR command, BTS6120 initializes this partition 6577 ; map so that unit 0 accesses partition 0, unit 1 accesses partition 1, and 6578 ; so on up through unit 7 and partition 7. This mapping remains in effect 6579 ; until it is changed by either the PM command, or the Set IDE Disk Partition 6580 ; Mapping PR0 function. 6581 ; 6582 ; The largest mass storage device supported by OS/8 is actually only 4095 6583 ; blocks, not 4096, and so the last block of every 2Mb partition is never 6584 ; used by OS/8. This block can, however, be accessed via the Read/Write IDE 6585 ; disk PR0 function (section 6.5), and it can be used to store the name, 6586 ; creation date, and other information about that partition. The OS/8 PART 6587 ; program uses this to allow partitions to be mounted on ID01 logical units 6588 ; by name rather than partition number. Named partitions are strictly a 6589 ; function of the OS/8 PART program and BTS6120 knows nothing about them. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 162 IDE Disk Interface BTS6120.PLX 6590 .TITLE IDE Disk Interface 6591 6592 6593 ; In the SBC6120, the IDE interface is implemented via a standard 8255 PPI, 6594 ; which gives us 24 bits of general purpose parallel I/O. Port A is connected 6595 ; the high byte (DD8..DD15) of the IDE data bus and port B is connected to 6596 ; the low byte (DD0..DD7). Port C supplies the IDE control signals as follow: 6597 ; 6598 ; C0..C2 -> DA0 .. 2 (i.e. device address select) 6599 ; C.3* -> DIOR L (I/O read) 6600 ; C.4* -> DIOW L (I/O write) 6601 ; C.5* -> RESET L 6602 ; C.6* -> CS1Fx L (chip select for the 1Fx register space) 6603 ; C.7* -> CS3Fx L ( " " " " 3Fx " " ) 6604 ; 6605 ; * These active low signals (CS1Fx, CS3Fx, DIOR, and DIOW) are inverted in 6606 ; the hardware so that writing a 1 bit to the register asserts the signal. 6607 ; 6608 ; One nice feature of the 8255 is that it allows bits in port C to be 6609 ; individually set or reset simply by writing the correct command word to the 6610 ; control register - it's not necessary to read the port, do an AND or OR, 6611 ; and write it back. We can use this feature to easily toggle the DIOR and 6612 ; DIOW lines with a single PWCR IOT. 6613 0222 IDEINP=222 ; set ports A and B as inputs, C as output 6614 0200 IDEOUT=200 ; set ports A and B (and C too) as outputs 6615 0007 SETDRD=007 ; assert DIOR L (PC.3) in the IDE interface 6616 0006 CLRDRD=006 ; clear " " " " " " " " 6617 0011 SETDWR=011 ; assert DIOW L (PC.4) in the IDE interface 6618 0010 CLRDWR=010 ; clear " " " " " " " " 6619 0013 SETDRE=013 ; assert DRESET L (PC.5) in the IDE interface 6620 0012 CLRDRE=012 ; clear " " " " " " " " 6621 6622 ; Standard IDE registers... 6623 ; (Note that these are five bit addresses that include the two IDE CS bits, 6624 ; CS3Fx (AC4) and CS1Fx (AC5). The three IDE register address bits, DA2..DA0 6625 ; correspond to AC9..AC11. 6626 0100 CS1FX=100 ; PC.6 selects the 1Fx register space 6627 0200 CS3FX=200 ; PC.7 " " 3Fx " " " 6628 0100 REGDAT=CS1FX+0 ; data (R/W) 6629 0101 REGERR=CS1FX+1 ; error (R/O) 6630 0102 REGCNT=CS1FX+2 ; sector count (R;W) 6631 0103 REGLB0=CS1FX+3 ; LBA byte 0 (or sector number) R/W 6632 0104 REGLB1=CS1FX+4 ; LBA byte 1 (or cylinder low) R/W 6633 0105 REGLB2=CS1FX+5 ; LBA byte 2 (or cylinder high) R/W 6634 0106 REGLB3=CS1FX+6 ; LBA byte 3 (or device/head) R/W 6635 0107 REGSTS=CS1FX+7 ; status (R/O) 6636 0107 REGCMD=CS1FX+7 ; command (W/O) 6637 6638 ; IDE status register (REGSTS) bits... 6639 0200 STSBSY=0200 ; busy 6640 0100 STSRDY=0100 ; device ready 6641 0040 STSDF= 0040 ; device fault 6642 0020 STSDSC=0020 ; device seek complete 6643 0010 STSDRQ=0010 ; data request 6644 0004 STSCOR=0004 ; corrected data flag 6645 0001 STSERR=0001 ; error detected 6646 6647 ; IDE command codes (or at least the ones we use!)... 6648 0220 CMDEDD=220 ; execute device diagnostic 6649 0354 CMDIDD=354 ; identify device 6650 0040 CMDRDS=040 ; read sectors with retry 6651 0060 CMDWRS=060 ; write sectors with retry 6652 0341 CMDSUP=341 ; spin up 6653 0340 CMDSDN=340 ; spin down PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 163 Initialize IDE Drive and Interface BTS6120.PLX 6654 .TITLE Initialize IDE Drive and Interface 6655 6656 6657 ; This routine will initialize the IDE interface by configuring the 8255 6658 ; PPI and then asserting the IDE RESET signal to the drive. It then selects 6659 ; the master drive and waits for it to become ready, after which it returns. 6660 ; If there is no drive attached, or if the hardware is broken, then we'll time 6661 ; out after approximately 30 seconds of waiting for the drive to signal a 6662 ; ready status. 6663 ; 6664 ; Normally this routine will return with the AC and LINK both cleared, but 6665 ; if the drive reports an error then on return the LINK will be set and the 6666 ; drive's error status will be in the AC. In the case of a timeout, the 6667 ; LINK will be set and the AC will be -1 on return. 6668 11013 7200 IDEINI: CLA ; ... 6669 11014 3022 DCA DKSIZE ; zero means no disk is installed 6670 11015 1375 TAD [IDEINP] ; PPI ports A and B are input and C is output 6671 11016 6477 PWCR ; ... 6672 11017 6476 PWPC ; clear all port C control lines 6673 11020 1374 TAD [SETDRE] ; set RESET L 6674 11021 6477 PWCR ; ... 6675 11022 1377 TAD [-10] ; according to the ATA specification, 6676 11023 7001 IAC ; ... we must leave RESET asserted for at 6677 11024 7440 SZA ; ... least 25 microseconds 6678 11025 5223 JMP .-2 ; 6679 11026 1373 TAD [CLRDRE] ; deassert RESET L 6680 11027 6477 PWCR ; ... 6681 6682 11030 1372 TAD [345] ; select the master drive, 512 byte sectors, 6683 11031 4771 JMS @[IDEWRR] ; ... and logical block addressing (LBA) mode 6684 11032 0106 REGLB3 ; ... 6685 6686 11033 4770 JMS @[IDERDR] ; quick check: read status reg 6687 11034 0107 REGSTS ; ... 6688 11035 1367 TAD [-345] ; if it's the same value as the last write, 6689 11036 7440 SZA ; there is almost certainly nothing there 6690 11037 5766 JMP @[WREADY] ; something... do a more complete check 6691 6692 11040 7360 CLA CLL CML CMA ; return with AC = -1 and the LINK set 6693 11041 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 164 Identify IDE/ATA Device BTS6120.PLX 6694 .TITLE Identify IDE/ATA Device 6695 6696 6697 ; This routine will execute the ATA IDENTIFY DEVICE command and store the 6698 ; first 256 bytes of the result, in byte mode, in the panel memory buffer at 6699 ; DSKBUF. One thing to keep in mind is that ATAPI devices (e.g. CDROMs, ZIP 6700 ; disks, etc) ignore this command completely and respond to the ATAPI IDENTIFY 6701 ; PACKET DEVICE command instead. This means that if there are any ATAPI 6702 ; devices attached we'll never see them, which is fine since we don't 6703 ; understand how to talk to ATAPI devices anyway! 6704 ; 6705 ; The drive's response to IDENTIFY DEVICE will be 256 words of sixteen bit 6706 ; data full of device specific data - model number, manufacturer, serial 6707 ; number, drive geometry, maximum size, access time, and tons of other cool 6708 ; stuff. The RDIBUF routine would pack this sixteen bit data into twelve bit 6709 ; words by throwing away the upper four bits of each word, but that doesn't 6710 ; make sense in this case since we'd be destroying most of the useful 6711 ; information. Instead, this routine reads the data in an unpacked format and 6712 ; stores one eight bit byte per PDP-8 word. 6713 ; 6714 ; Unfortunately this would mean that we need a 512 word buffer to store the 6715 ; response, which is too big for our DSKBUF in panel memory. We're in luck, 6716 ; however, because of the 256 words (512 bytes) returned by this command the 6717 ; ATA specification only defines the first 128 - the remaining half of the 6718 ; data is "vendor specific" and undefined. This routine simply throws this 6719 ; part away, and only the first 128 words (256 bytes) of the drive's response 6720 ; are actually returned in the buffer. 6721 ; 6722 ; Like all the disk I/O routines, in the case of an error the LINK will 6723 ; be set and the contents of the drive's error register returned in the AC. 6724 11042 6205 DISKID: .PUSHJ @[WREADY] ; (just in case the drive is busy now) 11043 5766 6725 11044 7430 SZL ; any errors? 6726 11045 6225 .POPJ ; yes - we can go home early! 6727 11046 1365 TAD [CMDIDD] ; send the ATA identify device command 6728 11047 4771 JMS @[IDEWRR] ; by writing it to the command register 6729 11050 0107 REGCMD ; ... 6730 11051 6205 .PUSHJ @[WDRQ] ; the drive should ask to transfer data next 11052 5764 6731 11053 7430 SZL ; any errors? 6732 11054 6225 .POPJ ; yes - just give up 6733 6734 ; Get ready to ready to transfer data from the drive to our buffer... 6735 11055 1363 TAD [DSKBUF-1] ; setup BUFPTR to point to DSKBUF 6736 11056 3011 DCA BUFPTR ; ... 6737 11057 1362 TAD [-128.] ; transfer 128 words this time 6738 11060 3051 DCA XFRCNT ; ... 6739 11061 1375 TAD [IDEINP] ; set PPI ports A and B to input mode 6740 11062 6477 PWCR ; ... 6741 11063 1361 TAD [REGDAT] ; make sure the IDE data register is selected 6742 11064 6476 PWPC ; ... 6743 6744 ; Read 256 bytes into the caller's buffer, one byte per word. Big endian 6745 ; ordering (i.e. high byte first) is defined by the ATA specification to give 6746 ; the correct character order for ASCII strings in the device data (e.g. model 6747 ; number, serial number, manufacturer, etc). 6748 11065 1360 IDDEV1: TAD [SETDRD] ; assert DIOR 6749 11066 6477 PWCR ; ... 6750 11067 6470 PRPA ; read port A (the high byte) first 6751 11070 0357 AND [377] ; only eight bits are valid 6752 11071 3411 DCA @BUFPTR ; and store it in the buffer 6753 11072 6471 PRPB ; then read port B (the low byte) 6754 11073 0357 AND [377] ; ... 6755 11074 3411 DCA @BUFPTR ; ... 6756 11075 1356 TAD [CLRDRD] ; deassert DIOR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 165 Identify IDE/ATA Device BTS6120.PLX 6757 11076 6477 PWCR ; ... 6758 11077 2051 ISZ XFRCNT ; have we done all 256 bytes? 6759 11100 5265 JMP IDDEV1 ; nope - keep reading 6760 6761 ; We've read our 256 bytes, but the drive still has another 256 more waiting 6762 ; in the buffer. We need to read those and throw them away... 6763 11101 1362 TAD [-128.] ; we still need to read 128 more words 6764 11102 3051 DCA XFRCNT ; ... 6765 11103 1360 IDDEV2: TAD [SETDRD] ; assert DIOR 6766 11104 6477 PWCR ; ... 6767 11105 7000 NOP ; make sure the DIOR pulse is wide enough 6768 11106 7000 NOP ; ... 6769 11107 1356 TAD [CLRDRD] ; and then clear DIOR 6770 11110 6477 PWCR ; ... 6771 11111 2051 ISZ XFRCNT ; have we done all 128? 6772 11112 5303 JMP IDDEV2 ; nope - keep reading 6773 6774 ; Drives report the total number of LBA addressable sectors in words 6775 ; 60 and 61. Sectors are 512 bytes, so simply dividing this value by 2048 6776 ; gives us the total drive size in Mb. This code patches together twelve 6777 ; bits out of the middle of this doubleword, after throwing away the least 6778 ; significant 11 bits to divide by 2048. This allows us to determine the 6779 ; size of drives up to 4Gb in a single 12 bit word. 6780 11113 1755 TAD @[DSKBUF+170] ; get the high byte of the low word 6781 11114 7010 RAR ; throw away the 3 least significant 6782 11115 7012 RTR ; ... 6783 11116 0354 AND [37] ; keep just 5 bits from this byte 6784 11117 3022 DCA DKSIZE ; save it for a minute 6785 11120 1753 TAD @[DSKBUF+173] ; get the low byte of the high word 6786 11121 7006 RTL ; left justify the seven MSBs of it 6787 11122 7006 RTL ; ... 6788 11123 7004 RAL ; ... 6789 11124 0352 AND [7740] ; ... 6790 11125 1022 TAD DKSIZE ; put together all twelve bits 6791 11126 3022 DCA DKSIZE ; ... 6792 6793 ; All done - return success... 6794 11127 7300 CLA CLL ; return with the AC and LINK clear 6795 11130 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 166 Get IDE Disk Size ROM Call BTS6120.PLX 6796 .TITLE Get IDE Disk Size ROM Call 6797 6798 6799 ; The get IDE disk size call will return the size of the attached IDE/ATA 6800 ; disk, in megabytes. This call never fails - if no disk is attached it 6801 ; simply returns zero... 6802 ; 6803 ;CALL: 6804 ; PR0 / call SBC6120 ROM firmware 6805 ; 5 / subfunction for get disk size 6806 ; 6807 ; 6808 11131 7300 GETDKS: CLA CLL ; ignore anything in the AC 6809 11132 1022 TAD DKSIZE ; and return the disk size 6810 11133 6225 .POPJ ; that's all there is to it! 6811 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 6812 11200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 167 IDE Disk Primary Bootstrap BTS6120.PLX 6813 .TITLE IDE Disk Primary Bootstrap 6814 6815 ; This routine will read block zero from IDE disk unit zero into page 6816 ; zero of field zero of main memory. The next step in the usual boot sequence 6817 ; would be to start the secondary bootstrap, but that's up to the caller... 6818 11200 7240 IDBOOT: STA ; point the buffer to page 0 6819 11201 3011 DCA BUFPTR ; ... 6820 11202 1377 TAD [CDF 0] ; of field zero 6821 11203 3776 DCA @[BUFCDF+1] ; ... 6822 11204 3052 DCA BUFPNL ; of main memory 6823 11205 6201 CDF 0 ; PARMAP lives in field 0 6824 11206 1775 TAD @[PARMAP] ; get partition number of unit 0 6825 11207 6211 CDF 1 6826 11210 3020 DCA DKPART ; ... 6827 11211 3021 DCA DKRBN ; block zero 6828 11212 1374 TAD [-128.] ; we only need the first 1/2 of the block 6829 11213 5773 JMP @[DISKRD] ; ... 6830 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 168 Read and Write IDE Sectors BTS6120.PLX 6831 .TITLE Read and Write IDE Sectors 6832 6833 ; This routine will read a single sector from the attached IDE drive. 6834 ; The caller should set up DKPART and DKRBN with the disk partition and 6835 ; sector number, and BUFPTR, BUFCDF and BUFPNL with the address of a 6836 ; buffer in 6120 memory. If any errors are encountered, this routine will 6837 ; return with the LINK set and the drive's error status in the AC... 6838 ; side effect: BUFPTR is advanced by the read size 6839 ; HOOK: this function can be intercepted in order to connect a different 6840 ; device interface to all the commands and functions that use the disk 6841 11214 7000 DISKRD: NOP ; HOOK: disk read 6842 11215 7000 NOP 6843 11216 7000 NOP 6844 11217 3053 DCA BUFSIZ ; save the buffer size 6845 6846 ; See if there really is a hard disk attached. If not, then immediately 6847 ; take the error return with the AC set to -1. 6848 11220 1022 TAD DKSIZE ; if there is a disk attached 6849 11221 7640 SZA CLA ; then DKSIZE will be non-zero 6850 11222 5225 JMP DRD1 ; it is - it's safe to proceed 6851 11223 7360 CLA CLL CML CMA ; no disk - return LINK = 1 and AC = -1 6852 11224 6225 .POPJ ; and quit now 6853 6854 11225 6205 DRD1: .PUSHJ @[WREADY] ; wait for the drive to become ready 11226 5772 6855 11227 7430 SZL ; any errors detected?? 6856 11230 6225 .POPJ ; yes - quit now 6857 11231 6205 .PUSHJ SETLBA ; set up the disk's LBA registers 11232 5310 6858 11233 1371 TAD [CMDRDS] ; read sector with retry command 6859 11234 4770 JMS @[IDEWRR] ; write that to the command register 6860 11235 0107 REGCMD ; ... 6861 11236 6205 .PUSHJ @[WDRQ] ; now wait for the drive to finish 11237 5767 6862 11240 7430 SZL ; any errors detected? 6863 11241 6225 .POPJ ; yes - quit now 6864 11242 1053 TAD BUFSIZ ; no - transfer data 6865 11243 5766 JMP @[RDIBUF] ; ... from the sector buffer to memory 6866 6867 6868 ; This routine will write a single sector to the attached IDE drive. Except 6869 ; for the direction of data transfer, it's basically the same as DISKRD, 6870 ; including all parameters and error returns. 6871 ; HOOK: this function can be intercepted in order to connect a different 6872 ; device interface to all the commands and functions that use the disk 6873 11244 7000 DISKWR: NOP ; HOOK: disk write 6874 11245 7000 NOP 6875 11246 7000 NOP 6876 11247 3053 DCA BUFSIZ ; save the caller's record size 6877 6878 ; See if there really is a hard disk attached. If not, then immediately 6879 ; take the error return with the AC set to -1. 6880 11250 1022 TAD DKSIZE ; if there is a disk attached 6881 11251 7640 SZA CLA ; then DKSIZE will be non-zero 6882 11252 5255 JMP DWR1 ; it is - it's safe to proceed 6883 11253 7360 CLA CLL CML CMA ; no disk - return LINK = 1 and AC = -1 6884 11254 6225 .POPJ ; and quit now 6885 6886 11255 6205 DWR1: .PUSHJ @[WREADY] ; wait for the drive to become ready 11256 5772 6887 11257 7430 SZL ; did we encounter an error ? 6888 11260 6225 .POPJ ; yes - just give up now 6889 11261 6205 .PUSHJ SETLBA ; set up the disk address registers 11262 5310 6890 11263 1365 TAD [CMDWRS] ; write sector with retry command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 169 Read and Write IDE Sectors BTS6120.PLX 6891 11264 4770 JMS @[IDEWRR] ; write that to the command register 6892 11265 0107 REGCMD ; ... 6893 11266 6205 .PUSHJ @[WDRQ] ; wait for the drive to request data 11267 5767 6894 11270 7430 SZL ; did the drive detect an error instead? 6895 11271 6225 .POPJ ; yes - just give up 6896 11272 1053 TAD BUFSIZ ; nope - transfer the data 6897 11273 6205 .PUSHJ @[WRIBUF] ; ... to the sector buffer from memory 11274 5764 6898 6899 ; There's a subtle difference in the order of operations between reading and 6900 ; writing. In the case of writing, we send the WRITE SECTOR command to the 6901 ; drive, transfer our data to the sector buffer, and only then does the 6902 ; drive actually go out and access the disk. This means we have to wait 6903 ; one more time for the drive to actually finish writing, because only then 6904 ; can we know whether it actually worked or not! 6905 11275 5772 JMP @[WREADY] ; wait for the drive to finish writing PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 170 Spin Up and Spin Down IDE Drive BTS6120.PLX 6906 .TITLE Spin Up and Spin Down IDE Drive 6907 6908 6909 ; This routine will send a spin up command to the IDE drive and then wait 6910 ; for it to finish. This command will take a fairly long time under normal 6911 ; conditions. Worse, since this is frequently the first command we send to 6912 ; a drive, if there's no drive attached at all we'll have to wait for it 6913 ; to time out. If any errors are encountered then the LINK will be set on 6914 ; return and the contents of the drive's error register will be in the AC. 6915 11276 7200 SPINUP: CLA ; ... 6916 11277 1363 TAD [CMDSUP] ; send the spin up command to the drive 6917 11300 4770 JMS @[IDEWRR] ; by writing it to the command register 6918 11301 0107 REGCMD ; ... 6919 11302 5772 JMP @[WREADY] ; wait for the drive to become ready 6920 6921 6922 ; This routine will send a spin down command. Drives are not required by 6923 ; the standard to implement this command, so there's no guarantee that any 6924 ; thing will actually happen! 6925 11303 7200 SPINDN: CLA ; ... 6926 11304 1362 TAD [CMDSDN] ; send the spin down command to the drive 6927 11305 4770 JMS @[IDEWRR] ; ... 6928 11306 0107 REGCMD ; ... 6929 11307 5772 JMP @[WREADY] ; and wait for it to finish PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 171 Setup IDE Unit, LBA and Sector Count Registers BTS6120.PLX 6930 .TITLE Setup IDE Unit, LBA and Sector Count Registers 6931 6932 6933 ; This routine will set up the IDE logical block address (LBA) registers 6934 ; according to the current disk address in locations DKPART and DKRBN. On IDE 6935 ; drives the sector number is selected via the cylinder and sector registers in 6936 ; the register file, but in the case of LBA mode these registers simply form a 6937 ; 24 bit linear sector number. In this software the disk partition number, in 6938 ; DKPART, gives the upper twelve bits of the address and the current sector 6939 ; number, in DKRBN, gives the lower twelve bits. 6940 ; 6941 ; This routine does not detect any error conditions... 6942 11310 7200 SETLBA: CLA ; just in case! 6943 11311 1021 TAD DKRBN ; get the lower 12 bits of of the LBA 6944 11312 4770 JMS @[IDEWRR] ; and write the lowest 8 bits to LBA0 6945 11313 0103 REGLB0 ; (the upper 4 bits are ignored) 6946 11314 1021 TAD DKRBN ; now get the upper 4 bits of the sector number 6947 11315 7002 BSW ; shift right eight bits 6948 11316 7012 RTR ; ... 6949 11317 0361 AND [17] ; get rid of the extra junk 6950 11320 3344 DCA LBATMP ; ... 6951 11321 1020 TAD DKPART ; get the disk partition number 6952 11322 7006 RTL ; shift them left four bits 6953 11323 7006 RTL ; ... 6954 11324 0360 AND [360] ; and isolate just four bits of that 6955 11325 1344 TAD LBATMP ; and build the middle byte of the LBA 6956 11326 4770 JMS @[IDEWRR] ; set that register next 6957 11327 0104 REGLB1 ; ... 6958 11330 1020 TAD DKPART ; get the partition one more time 6959 11331 7012 RTR ; shift it right four more bits 6960 11332 7012 RTR ; ... 6961 11333 4770 JMS @[IDEWRR] ; to make the upper byte of the 24 bit LBA 6962 11334 0105 REGLB2 ; ... 6963 6964 ; Note that the final four bits of the LBA are in LBA3 (the head and drive 6965 ; select register). Since we can only support 24 bit LBAs, these are unused. 6966 ; The IDEINI routine initializes them to zero at the same time it selects the 6967 ; master drive, and we never change 'em after that. At the same time, IDEINI 6968 ; also selects LBA addressing mode (which is obviously very important to us!) 6969 ; and 512 byte sectors. 6970 11335 1362 TAD [340] ; select the master drive, 512 byte sectors, 6971 11336 4770 JMS @[IDEWRR] ; ... and logical block addressing (LBA) mode 6972 11337 0106 REGLB3 ; ... 6973 6974 ; Always load the sector count register with one... 6975 11340 7201 NL0001 ; write 1 6976 11341 4770 JMS @[IDEWRR] ; ... 6977 11342 0102 REGCNT ; to the sector count register 6978 11343 6225 .POPJ ; that's all we have to do 6979 6980 ; Temporary storage for SETLBA... 6981 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 13-JAN-24 18:41:12 Page 172 Setup IDE Unit, LBA and Sector Count Registers BTS6120.PLX 11375 0020 11376 2212 11377 6201 6982 11400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 173 Wait for IDE Drive Ready BTS6120.PLX 6983 .TITLE Wait for IDE Drive Ready 6984 6985 6986 ; This routine tests for the DRIVE READY bit set in the status register and 6987 ; at the same time for the DRIVE BUSY bit to be clear. READY set means that 6988 ; the drive has power and is spinning, and BUSY clear means that it isn't 6989 ; currently executing a command. The combination of these two conditions means 6990 ; that the drive is ready to accept another command. Normally this routine 6991 ; will return with both the AC and the LINK cleared, however if the drive sets 6992 ; the ERROR bit in its status register then it will return with the LINK set 6993 ; and the contents of the drive's error register in the AC. 6994 ; 6995 ; If there is no drive connected, or if the drive fails for some reason, 6996 ; then there is the danger that this routine will hang forever. To avoid 6997 ; that it also implements a simple timeout, and if the drive doesn't become 6998 ; ready within a certain period of time it will return with the LINK set and 6999 ; the AC equal to -1. If the system has just been powered up, then we'll 7000 ; have to wait for the drive to spin up before it becomes ready, and that can 7001 ; take a fairly long time. To be safe, the timeout currently stands at a 7002 ; full 30 seconds! 7003 11400 1377 WREADY: TAD [7550] ; initialize the outer timeout counter 7004 11401 3225 DCA RDYTMO+1 ; ... 7005 11402 3224 DCA RDYTMO ; and the inner counter is always cleared 7006 11403 4776 WREAD1: JMS @[IDERDR] ; go read the status register 7007 11404 0107 REGSTS ; (register to read) 7008 11405 7110 CLL RAR ; test the error bit first (AC11) 7009 11406 7430 SZL ; ??? 7010 11407 5775 JMP @[DRVERR] ; give up now if the drive reports an error 7011 11410 7004 RAL ; restore the original status 7012 11411 0374 AND [STSBSY+STSRDY] ; test both the READY and BUSY bits 7013 11412 1373 TAD [-STSRDY] ; is READY set and BUSY clear? 7014 11413 7020 CML ; (the last TAD will have set the link!) 7015 11414 7650 SNA CLA ; ??? 7016 11415 6225 .POPJ ; yes - return now with the AC and LINK clear 7017 11416 2224 ISZ RDYTMO ; increment the inner timeout counter 7018 11417 5203 JMP WREAD1 ; no overflow yet 7019 11420 2225 ISZ RDYTMO+1 ; when the inner counter overflows, increment 7020 11421 5203 JMP WREAD1 ; ... the outer counter too 7021 7022 ; Here in the case of a drive time out... 7023 11422 7360 CLA CLL CML CMA ; return with AC = -1 and the LINK set 7024 11423 6225 .POPJ ; ... 7025 7026 ; Temporary storage for WREADY... 7027 11424 RDYTMO: .BLOCK 2 ; a double word time out counter 7028 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 174 Wait for IDE Data Request BTS6120.PLX 7029 .TITLE Wait for IDE Data Request 7030 7031 ; This routine will wait for the DRQ bit to set in the drive status register. 7032 ; This bit true when the drive is ready to load or unload its sector buffer, 7033 ; and normally a call to this routine will be immediately followed by a call 7034 ; to ether RDIBUF or WRIBUF. Normally this routine will return with both the 7035 ; LINK and the AC cleared, however if the drive sets its error bit then the 7036 ; LINK will be 1 on return and the drive's error status will be in the AC. 7037 ; 7038 ; WARNING - unlike WREADY, this routine does not have a timeout! 7039 11426 4776 WDRQ: JMS @[IDERDR] ; read the drive status register 7040 11427 0107 REGSTS ; ... 7041 11430 7110 CLL RAR ; test the error bit (AC11) 7042 11431 7430 SZL ; is it set? 7043 11432 5242 JMP DRVERR ; yes - give the error return 7044 11433 7004 RAL ; no - restore the original status value 7045 11434 0372 AND [STSBSY+STSDRQ] ; and test the BUSY and DRQ flags 7046 11435 1371 TAD [-STSDRQ] ; wait for BUSY clear and DRQ set 7047 11436 7020 CML ; (the last TAD will have set the link!) 7048 11437 7640 SZA CLA ; well? 7049 11440 5226 JMP WDRQ ; nope - keep waiting 7050 11441 6225 .POPJ ; yes - return with AC and LINK cleared! 7051 7052 ; We get here if the drive sets the error flag in the status register. In 7053 ; this case we return with the link bit set and the contents of the drive 7054 ; error register in the AC. 7055 11442 4776 DRVERR: JMS @[IDERDR] ; read the drive error register 7056 11443 0101 REGERR ; ... 7057 11444 7120 STL ; and be sure the link is set 7058 11445 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 175 RAM Disk Diagnostics BTS6120.PLX 7059 .TITLE RAM Disk Diagnostics 7060 7061 ; This routine will do a simple test of the RAM disk array to determine 7062 ; whether each SRAM chip, from 0 to 7, is installed. If a given chip is 7063 ; installed, then we do another simple test to determine whether it is a 7064 ; 512K or 128K device, and then update the RDSIZE array accordingly. 7065 ; Because of the way disk sectors are laid out, only the first 4032 bytes 7066 ; (21 * 192) of every 4Kb bank are actually used. The last 64 bytes of each 7067 ; bank are available to us to use any way we like, including as a RAM test. 7068 ; 7069 ; There's one nasty complication here - the pin that corresponds to A17 on 7070 ; the 512K SRAM chips is actually an alternate chip enable on the 128K chips. 7071 ; Worse, this alternate enable is active HIGH, which means that A17 must be 7072 ; one or 128K chips won't talk at all. Fortunately, the pin that corresponds 7073 ; to A18 is a no connect on the 128K chips, so we can safely leave it zero. 7074 ; This explains the strange bank numbers selected in this test! 7075 ; 7076 11446 3043 RDTEST: DCA RAMSIZ ; clear the total RAM size 7077 7078 ; Clear the entire RDSIZE array, even if we have fewer than 8 SRAMs... 7079 11447 1371 TAD [-10] ; RDZISE always holds 8 units 7080 11450 3024 DCA RDUNIT ; count them here 7081 11451 1370 TAD [RDSIZE-1] ; and point to the RDSIZE array 7082 11452 3012 DCA XX1 ; (an auto-index register) 7083 11453 3412 DCA @XX1 ; clear another entry 7084 11454 2024 ISZ RDUNIT ; have we done them all 7085 11455 5253 JMP .-2 ; no - keep clearing 7086 ; yes - start testing with RDUNIT = 0 ! 7087 7088 ; First test to see if this chip is even installed by writing alternating 7089 ; bit patterns to the last two locations and reading them back. If that works, 7090 ; then there must be something there! 7091 11456 6205 RDTES0: .PUSHJ @[RAMSEL] ; and set up RAMCDF and SIZPTR 11457 5767 7092 11460 1366 TAD [32.] ; test bank 32 so that A17 will be set 7093 11461 6410 LDAR ; ... 7094 11462 4765 JMS @[RAMCDF] ; change the DF to select the unit 7095 11463 6403 MM3 ; and enable the SRAM array 7096 11464 1364 TAD [252] ; write alternating bits to the last two bytes 7097 11465 3763 DCA @[7776] ; ... 7098 11466 1362 TAD [125] ; ... 7099 11467 3761 DCA @[7777] ; ... 7100 11470 1763 TAD @[7776] ; now read 'em back 7101 11471 1761 TAD @[7777] ; and add them up 7102 11472 7001 IAC ; the sum should be 377, so make it 400 7103 11473 0360 AND [377] ; and remember RAM disk is only 8 bits wide 7104 11474 7640 SZA CLA ; did it work?? 7105 11475 5310 JMP RDTES1 ; no - this chip doesn't exist 7106 7107 ; Some kind of SRAM chip is installed, and now we need to decide whether its 7108 ; 128K or 512K. The 128K chips ignore A18, so one easy test is to select 7109 ; bank 96 (which, to a 128K chip is the same as bank 32), zero out a location 7110 ; that we just tested, and then go back to bank 32 to see if it changed. 7111 11476 1357 TAD [96.] ; select bank 96 7112 11477 6410 LDAR ; which doesn't exist in a 128K chip 7113 11500 3761 DCA @[7777] ; this location in bank 0 used to hold 125 7114 11501 1366 TAD [32.] ; back to bank 32 7115 11502 6410 LDAR ; ... 7116 11503 1761 TAD @[7777] ; and see what we've got 7117 11504 0360 AND [377] ; remember RAM disk is only 8 bits wide 7118 11505 7640 SZA CLA ; if it's zero, then we have a 128K chip 7119 11506 1356 TAD [RAM512-RAM128]; nope - this must be a full 512K SRAM! 7120 11507 1355 TAD [RAM128] ; only 128K, but better than nothing 7121 7122 ; Store the chip size in RDSIZE and accumulate the total size... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 176 RAM Disk Diagnostics BTS6120.PLX 7123 11510 6402 RDTES1: MM2 ; return to the default memory map 7124 11511 6211 CDF 1 ; and field 7125 11512 3444 DCA @SIZPTR ; store the size in RDSIZE[unit] 7126 11513 1444 TAD @SIZPTR ; ... 7127 11514 7450 SNA ; was there any chip here at all? 7128 11515 5325 JMP RDTES2 ; no - we can skip this part 7129 11516 7710 SPA CLA ; KLUDGE - skip if this was a 128K chip 7130 11517 1354 TAD [512.-128.] ; add 512K to the total RAM size 7131 11520 1353 TAD [128.] ; add 128K " " " " " 7132 ; Now it's time for a major hack. If we have a full eight 512K SRAM chips 7133 ; installed, then RAMSIZ will be 4096KB, or zero in the twelve bit world! 7134 ; If we ever find that, after adding the size of this chip, RAMSIZ is zero 7135 ; then we know that situation has occurred. The only thing we can to is to 7136 ; set RAMSIZ to 4095 instead of 4096 - that way, at least, it doesn't look 7137 ; like we have nothing... 7138 11521 1043 TAD RAMSIZ ; ... 7139 11522 7450 SNA ; did we reach 4096K ??? 7140 11523 7240 STA ; yes - set it to 4095 instead 7141 11524 3043 DCA RAMSIZ ; ... 7142 7143 ; On to the next unit, if there are any more left... 7144 11525 2024 RDTES2: ISZ RDUNIT ; go on to the next unit 7145 11526 1046 TAD RDTYPE ; get the RAM disk type 7146 11527 7700 SMA CLA ; skip if it's a DS1221 or IOB6120 card 7147 11530 1352 TAD [-4] ; no - the DS1231 card supports 8 units 7148 11531 1352 TAD [-4] ; and the others only 4 7149 11532 1024 TAD RDUNIT ; have we done all eight ? 7150 11533 7640 SZA CLA ; ??? 7151 11534 5256 JMP RDTES0 ; no - keep checking 7152 11535 1043 TAD RAMSIZ ; yes - return the total RAM disk size 7153 11536 6225 .POPJ ; and that's it 7154 11552 7774 11553 0200 11554 0600 11555 1240 11556 3740 11557 0140 11560 0377 11561 7777 11562 0125 11563 7776 11564 0252 11565 0743 11566 0040 11567 0712 11570 0032 11571 7770 11572 0210 11573 7700 11574 0300 11575 1442 11576 2101 11577 7550 7155 11600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 177 Write IDE Sector Buffer BTS6120.PLX 7156 .TITLE Write IDE Sector Buffer 7157 7158 7159 ; This routine will write PDP-8 twelve bit words to the IDE drive's sixteen 7160 ; bit data (sector) buffer. IDE drives naturally transfer data in sixteen bit 7161 ; words, and we simply store each twelve bit word zero extended. This wastes 7162 ; 25% of the drive's capacity, but in these days of multiple gigabyte disks, 7163 ; that hardly seems important. This also means that 256 PDP-8 words exactly 7164 ; fill one IDE sector, which is very convenient for OS/8! 7165 ; 7166 ; The caller is expected to set up BUFPTR, BUFCDF and BUFPNL to point to the 7167 ; buffer in 6120 memory. The negative of the buffer size should be passed in 7168 ; the AC, however we must always write exactly 256 words to the drive regard- 7169 ; less of the buffer size. If the buffer is smaller than that, then the last 7170 ; word is simply repeated until we've filled the entire sector. This is 7171 ; necessary for OS/8 handler "half block" writes. 7172 ; 7173 ; This routine does not wait for the drive to set DRQ, nor does it check the 7174 ; drive's status for errors. Those are both up to the caller. 7175 11600 3053 WRIBUF: DCA BUFSIZ ; save the actual buffer size 7176 11601 1377 TAD [-256.] ; but always transfer 256 words, regardless 7177 11602 3051 DCA XFRCNT ; ... 7178 11603 1376 TAD [IDEOUT] ; and set ports A and B to output mode 7179 11604 6477 PWCR ; ... 7180 11605 1375 TAD [REGDAT] ; make sure the IDE data register is addressed 7181 11606 6476 PWPC ; ... 7182 11607 4774 JMS @[BUFCDF] ; change to the buffer's field 7183 7184 ; Transfer 256 twelve bit words into 256 sixteen bit words... 7185 11610 1411 WRIBU1: TAD @BUFPTR ; and get the next data word 7186 11611 3312 DCA BUFTMP ; save it temporarily 7187 11612 1312 TAD BUFTMP ; ... 7188 11613 6475 PWPB ; write the lowest 8 bits to port B 7189 11614 1312 TAD BUFTMP ; then get the upper four bits 7190 11615 7002 BSW ; ... 7191 11616 7012 RTR ; ... 7192 11617 0373 AND [17] ; ensure that the extra bits are zero 7193 11620 6474 PWPA ; and write the upper four bits to port A 7194 11621 1372 TAD [SETDWR] ; assert DIOW 7195 11622 6477 PWCR ; ... 7196 11623 1371 TAD [CLRDWR] ; and then clear it 7197 11624 6477 PWCR ; ... 7198 11625 2051 ISZ XFRCNT ; have we done 256 words?? 7199 11626 7410 SKP ; no - keep going 7200 11627 5240 JMP WRIBU3 ; yes - always stop now 7201 11630 2053 ISZ BUFSIZ ; have we filled the buffer ? 7202 11631 5210 JMP WRIBU1 ; nope - keep copying 7203 7204 ; Here when we've emptied the 6120 buffer, but if we haven't done 256 words 7205 ; we have to keep going until we've filled the drive's sector buffer. All we 7206 ; need to do is to keep asserting DIOW, which simply repeats the last word 7207 ; written! 7208 11632 1372 WRIBU2: TAD [SETDWR] ; assert DIOW 7209 11633 6477 PWCR ; ... 7210 11634 1371 TAD [CLRDWR] ; and deassert DIOW 7211 11635 6477 PWCR ; ... 7212 11636 2051 ISZ XFRCNT ; have we finished the sector? 7213 11637 5232 JMP WRIBU2 ; nope 7214 7215 ; Restore the PPI ports to input mode and return. Note that some disk 7216 ; I/O routines JMP to WRIBUF as the last step, so it's important that we 7217 ; always return with the AC and LINK cleared to indicate success. 7218 11640 6211 WRIBU3: CDF 1 ; return to our field 7219 11641 6276 SPD ; and to panel memory 7220 11642 1370 TAD [IDEINP] ; reset ports A and B to input PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 178 Write IDE Sector Buffer BTS6120.PLX 7221 11643 6477 PWCR ; ... 7222 11644 7300 CLA CLL ; return success 7223 11645 6225 .POPJ ; all done here PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 179 Read IDE Sector Buffer BTS6120.PLX 7224 .TITLE Read IDE Sector Buffer 7225 7226 7227 ; This routine will read sixteen bit words from the IDE drive's sector 7228 ; buffer and store them in twelve bit PDP-8 memory words. Data is converted 7229 ; from sixteen to twelve bits by the simple expedient of discarding the upper 7230 ; four bits of each word - it can't get much easier than that! 7231 ; 7232 ; The caller is expected to set up BUFPTR, BUFCDF and BUFPNL to point to the 7233 ; buffer in 6120 memory. The negative of the buffer size should be passed in 7234 ; the AC. This is the number of words that will be stored in the buffer, 7235 ; however we'll always read exactly 256 words from the drive regardless of 7236 ; the buffer size. If the buffer is smaller than this then the extra words 7237 ; are simply discarded. This is necessary for OS/8 handler "half block" reads. 7238 ; 7239 ; Like WRIBUF, this routine does not wait for the drive to set DRQ, nor does 7240 ; it check the drive's status for errors. Those are both up to the caller. 7241 11646 3053 RDIBUF: DCA BUFSIZ ; save the actual buffer size 7242 11647 1377 TAD [-256.] ; but always transfer 256 words, regardless 7243 11650 3051 DCA XFRCNT ; ... 7244 11651 1370 TAD [IDEINP] ; and set ports A and B to input mode 7245 11652 6477 PWCR ; ... 7246 11653 1375 TAD [REGDAT] ; make sure the IDE data register is addressed 7247 11654 6476 PWPC ; ... 7248 11655 4774 JMS @[BUFCDF] ; change to the buffer's field 7249 7250 ; Transfer 256 twelve bit words... 7251 11656 1367 RDIBU1: TAD [SETDRD] ; assert DIOR 7252 11657 6477 PWCR ; ... 7253 11660 6471 PRPB ; capture the lower order byte 7254 11661 0366 AND [377] ; remove any junk bits, just in case 7255 11662 3312 DCA BUFTMP ; and save that for a minute 7256 11663 6470 PRPA ; then capture the high byte 7257 11664 0373 AND [17] ; we only want four bits from that 7258 11665 7002 BSW ; shift it left eight bits 7259 11666 7106 CLL RTL ; ... 7260 11667 1312 TAD BUFTMP ; assemble a complete twelve bit word 7261 11670 3411 DCA @BUFPTR ; and store it in the buffer 7262 11671 1365 TAD [CLRDRD] ; finally we can deassert DIOR 7263 11672 6477 PWCR ; ... 7264 11673 2051 ISZ XFRCNT ; have we done 256 words?? 7265 11674 7410 SKP ; no - keep going 7266 11675 5306 JMP RDIBU3 ; yes - always stop now 7267 11676 2053 ISZ BUFSIZ ; have we filled the buffer ? 7268 11677 5256 JMP RDIBU1 ; nope - keep copying 7269 7270 ; Here when we've filled the 6120 buffer, but if we haven't done 256 words 7271 ; we have to keep going until we've emptied the drive's sector buffer too. 7272 ; All we need to do is to keep asserting DIOR - there's no need to actually 7273 ; capture the data! 7274 11700 1367 RDIBU2: TAD [SETDRD] ; assert DIOR 7275 11701 6477 PWCR ; ... 7276 11702 1365 TAD [CLRDRD] ; and deassert DIOR 7277 11703 6477 PWCR ; ... 7278 11704 2051 ISZ XFRCNT ; have we finished the sector? 7279 11705 5300 JMP RDIBU2 ; nope 7280 7281 ; Restore the ROM field and memory space and return. Note that some disk 7282 ; I/O routines JMP to RDIBUF as the last step, so it's important that we 7283 ; always return with the AC and LINK cleared to indicate success. 7284 11706 6211 RDIBU3: CDF 1 ; ... 7285 11707 6276 SPD ; ... 7286 11710 7300 CLA CLL ; always return success 7287 11711 6225 .POPJ ; all done here 7288 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 180 Read IDE Sector Buffer BTS6120.PLX 7289 ; Temporary storage for RDIBUF and WRIBUF... 7290 11712 BUFTMP: .BLOCK 1 ; temporary for packing and unpacking 7291 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 181 Initialize Disk Partition Map BTS6120.PLX 7292 .TITLE Initialize Disk Partition Map 7293 7294 7295 ; This routine will initialize the disk partition map so that unit 0 7296 ; maps to partition 0, unit 1 maps to partition 1, etc... This is the 7297 ; default partition mapping used after a power on and remains in effect 7298 ; until changed by an OS/8 program with the "Set Partition Mapping" PR0 7299 ; subfunction. 7300 7301 11713 7200 INIPMP: CLA ; just in case... 7302 11714 1364 TAD [-8.] ; we are going to init 8 units 7303 11715 3020 DCA DKPART 7304 11716 1373 TAD [PARMAP-1] ; set up an auto index register 7305 11717 3012 DCA XX1 ; ... to address the partition map 7306 11720 6402 MM2 7307 11721 7215 INIPM1: NL0010 7308 11722 1020 TAD DKPART ; get the current partition/unit 7309 11723 6201 CDF 0 7310 11724 3412 DCA @XX1 ; and set the next entry in the map 7311 11725 6211 CDF 1 7312 11726 2020 ISZ DKPART 7313 11727 5321 JMP INIPM1 ; ... 7314 11730 7300 CLA CLL 7315 11731 6225 .POPJ 7316 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 182 Set Disk Partition Map ROM Call BTS6120.PLX 7317 .TITLE Set Disk Partition Map ROM Call 7318 7319 7320 ; This routine handles the "Set Disk Partition Mapping" (6) PR0 subfunction, 7321 ; which simply sets the partition number for the specified OS/8 unit. This 7322 ; change takes effect immediately, so if you've booted from the IDE disk 7323 ; you'll want to be a little careful about remapping the system partition! 7324 ; This function returns with the LINK set if an error occurs, currently the 7325 ; only failure that can happen is if the unit number is .GT. 7. Note that 7326 ; no range checking is done on the partition number to ensure that it fits 7327 ; within the disk size - if it doesn't we'll simply get I/O errors when OS/8 7328 ; attempts to access that partition. 7329 ; 7330 ;CALL: 7331 ; TAD (part / load the partition number into the AC 7332 ; PR0 / invoke the ROM monitor 7333 ; 6 / subfunction for Set disk partition 7334 ; / OS/8 unit to be changed, 0..7 7335 ; / LINK set if unit .GT. 7 7336 ; 7337 11732 3020 SETPMP: DCA DKPART ; save the partition number for a minute 7338 11733 6205 .PUSHJ @[GETARG] ; and get the unit number 11734 5763 7339 11735 3023 DCA DKUNIT ; ... 7340 11736 1023 TAD DKUNIT ; ... 7341 11737 7100 CLL ; be sure the link is in a known state 7342 11740 1364 TAD [-10] ; see if the unit number is legal 7343 11741 7630 SZL CLA ; the link will be set if it isn't 7344 11742 6225 .POPJ ; take the error return w/o changing anything 7345 11743 1023 TAD DKUNIT ; construct an index to the partition map 7346 11744 1373 TAD [PARMAP-1] ; ... 7347 11745 3012 DCA XX1 ; ... 7348 11746 1020 TAD DKPART ; then get the desired partition number 7349 11747 6201 CDF 0 ; PARAM lives in field 0 7350 11750 3412 DCA @XX1 ; and change it 7351 11751 6222 CIF 2 7352 11752 6205 .PUSHJ @[WRPSS] ; update NVRAM 11753 5762 7353 11754 7300 CLL CLA 7354 11755 6225 .POPJ ; return with the LINK and AC both clear 7355 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 7356 12000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 183 Get Disk Partition Map ROM Call BTS6120.PLX 7357 .TITLE Get Disk Partition Map ROM Call 7358 7359 7360 ; This routine handles the "Get Disk Partition Mapping" (7) PR0 subfunction, 7361 ; which simply returns the partition number currently associated with a 7362 ; specific OS/8 unit. The only way it can fail is if the unit number is 7363 ; greater than 7! 7364 ; 7365 ;CALL: 7366 ; PR0 / invoke the ROM monitor 7367 ; 7 / subfunction for get disk partition 7368 ; / OS/8 unit to be changed, 0..7 7369 ; / with partition number in the AC 7370 ; 7371 12000 6205 GETPMP: .PUSHJ @[GETARG] ; and get the unit number 12001 5777 7372 12002 3023 DCA DKUNIT ; ... 7373 12003 7100 CLL ; be sure the link is in a known state 7374 12004 1376 TAD [-10] ; see if the unit number is legal 7375 12005 1023 TAD DKUNIT ; ... 7376 12006 7630 SZL CLA ; the link will be set if it isn't 7377 12007 6225 .POPJ ; take the error return 7378 12010 1023 TAD DKUNIT ; construct an index to the partition map 7379 12011 1375 TAD [PARMAP-1] ; ... 7380 12012 3012 DCA XX1 ; ... 7381 12013 6201 CDF 0 ; PARMAP lives in field 0 7382 12014 1412 TAD @XX1 ; and get the current partition 7383 12015 6211 CDF 1 7384 12016 6225 .POPJ ; return with partition in the AC and LINK=0 7385 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 184 IDE Disk Read/Write ROM Call BTS6120.PLX 7386 .TITLE IDE Disk Read/Write ROM Call 7387 7388 7389 ; The calling sequence for the PR0 IDE disk R/W function is: 7390 ; 7391 ; PR0 7392 ; 0004 / panel function code for IDE disk I/O 7393 ; / R/W bit, page count, buffer field and unit 7394 ; / buffer address 7395 ; / starting block number 7396 ; / if any errors occur, the LINK will be set and the 7397 ; / the drive's error register are in the AC 7398 ; 7399 ; Except for the function code, the use of block numbers instead of page 7400 ; numbers, and the error codes, this calling sequence is identical to the 7401 ; RAM disk I/O PR0 subfunction! 7402 ; 7403 12017 6205 DISKRW: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 12020 5774 7404 12021 6205 .PUSHJ @[GETARG] ; and lastly get the disk block 12022 5777 7405 12023 3021 DCA DKRBN ; ... 7406 7407 ; The unit number is really just an index into the partition table and, 7408 ; since it's limited to three bits and eight units are supported, there's 7409 ; no need to range check it! 7410 12024 1047 DKRW0: TAD MUUO ; get the unit number 7411 12025 0373 AND [7] ; ... 7412 12026 1375 TAD [PARMAP-1] ; create an index to the partition table 7413 12027 3012 DCA XX1 ; ... 7414 12030 6201 CDF 0 ; PARMAP lives in field 0 7415 12031 1412 TAD @XX1 ; get the actual partition number 7416 12032 6211 CDF 1 7417 12033 3020 DCA DKPART ; ... that's mapped to this unit 7418 7419 ; Set up a pointer to the I/O routine. All of the rest of this code is 7420 ; independent of the direction of data flow... 7421 12034 1047 TAD MUUO ; get the function code 7422 12035 7700 SMA CLA ; should we read (0) or write (1) ? 7423 12036 1372 TAD [DISKRD-DISKWR]; ... read 7424 12037 1371 TAD [DISKWR] ; ... write 7425 12040 3260 DCA DISKIO ; save the address of the routine 7426 7427 ; We must take a minute out to share a word about pages vs blocks. An OS/8 7428 ; handler call specifies the size of the data to be read or written in pages, 7429 ; which are 128 words or exactly 1/2 of a 256 word disk block. This raises 7430 ; the unfortunate possibility that a program could ask to transfer an odd 7431 ; number of pages, which would mean that we'd need to read or write half a 7432 ; block! We can't ignore this problem because it really does happen and there 7433 ; really are OS/8 programs that attempt to transfer an odd number of pages. 7434 ; 7435 ; This is primarily an issue for reading, because if an odd number of pages 7436 ; are to be read we must be very careful to stop copying data to memory after 7437 ; 128 words. If we don't, a page of memory will be corrupted by being over 7438 ; written with the second half of the last disk block! It's also permitted in 7439 ; OS/8 to write an odd number of pages, but since many OS/8 mass storage 7440 ; devices have 256 word sectors it isn't always possible to write half a 7441 ; block. In this case it's undefined what gets written to the last half of 7442 ; the final block - it could be zeros, random garbage, or anything else. 7443 7444 ; This loop reads or writes pages 'till we've done all we're supposed to... 7445 12041 2054 DKRW1: ISZ RWCNT ; is there an odd page left over? 7446 12042 7410 SKP ; nope - it's safe to do a full block 7447 12043 5256 JMP DKRW2 ; yes - go transfer a half block and quit 7448 12044 1370 TAD [-256.] ; transfer two pages this time PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 185 IDE Disk Read/Write ROM Call BTS6120.PLX 7449 12045 6205 .PUSHJ @DISKIO ; either read or write 12046 5660 7450 12047 7430 SZL ; were there any errors? 7451 12050 6225 .POPJ ; yes - just abort the transfer now 7452 12051 2021 ISZ DKRBN ; increment the block number for next time 7453 12052 7000 NOP ; (this should never happen, but...) 7454 12053 2054 ISZ RWCNT ; are there more pages left to do ? 7455 12054 5241 JMP DKRW1 ; yup - keep going 7456 12055 6225 .POPJ ; all done - return AC = LINK = 0 7457 7458 ; Here to transfer one, final, half block... 7459 12056 1367 DKRW2: TAD [-128.] ; only do a single page this time 7460 12057 5660 JMP @DISKIO ; transfer it and we're done 7461 7462 ; Local storage for DISKRW... 7463 12060 DISKIO: .BLOCK 1 ; gets a pointer to either DISKRD or DISKWR 7464 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 186 Write IDE Register BTS6120.PLX 7465 .TITLE Write IDE Register 7466 7467 7468 ; This routine will write an eight bit value to any IDE drive register, 7469 ; except the data regsister, by toggling all the appropriate PPI port lines. 7470 ; The address of the register, which should include the CS1Fx and CS3Fx bits, 7471 ; is passed in line and the byte to be written is passed in the AC. Note that 7472 ; all IDE registers, with the exception of the data register, are eight bits 7473 ; wide so there's never a need to worry about the upper byte! 7474 ; 7475 ;CALL: 7476 ; TAD [value] ; eight bit value to write to the IDE register 7477 ; JMS IDEWRR 7478 ; xxxx ; IDE register number, plus CS1Fx and CS3Fx bits 7479 ; 7480 ; 7481 12061 0000 IDEWRR: 0 ; CALL HERE WITH A JMS!!! 7482 12062 3322 DCA IDETMP ; save the value to write for a minute 7483 12063 1366 TAD [IDEOUT] ; set ports A and B to output mode 7484 12064 6477 PWCR ; write the PPI control register 7485 12065 1661 TAD @IDEWRR ; get the IDE register address 7486 12066 2261 ISZ IDEWRR ; (skip it when we return) 7487 12067 6476 PWPC ; send the address to the drive via port C 7488 7489 ; Note that we don'e bother to drive the upper data byte (D8..D15) with any 7490 ; particular value. The PPI will have set these bits to zero when we changed 7491 ; the mode to output, but the drive will ignore them anyway. 7492 12070 1322 TAD IDETMP ; get the original data back 7493 12071 6475 PWPB ; (port B drives DD0..DD7) 7494 12072 1365 TAD [SETDWR] ; assert DIOW 7495 12073 6477 PWCR ; ... 7496 12074 1364 TAD [CLRDWR] ; and then clear it 7497 12075 6477 PWCR ; ... 7498 7499 ; We always leave our side of the PPI data bus (e.g. ports A and B) in 7500 ; input mode to avoid any accidental contention should the drive decide it 7501 ; wants to output data for some unknown reason. 7502 12076 1363 TAD [IDEINP] ; set ports A and B to input mode 7503 12077 6477 PWCR ; ... (but C is still an output) 7504 12100 5661 JMP @IDEWRR ; that's it! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 187 Read IDE Register BTS6120.PLX 7505 .TITLE Read IDE Register 7506 7507 7508 ; This routine will read one IDE drive register and return the value in the 7509 ; AC. all IDE registers, with the exception of the data register, are always 7510 ; eight bits wide so there's no need to worry about the upper byte here. We 7511 ; simply ignore it. The address of the register to be read should be passed 7512 ; inline, following the call to this procedure. 7513 ; 7514 ;CALL 7515 ; JMS IDERDR 7516 ; xxxx ; IDE register number, including CS1Fx and CS3Fx bits 7517 ; 7518 ; 7519 12101 0000 IDERDR: 0 ; CALL HERE WITH A JMS!! 7520 12102 7200 CLA ; just in case... 7521 12103 1363 TAD [IDEINP] ; set ports A and B to input 7522 12104 6477 PWCR ; ... (this should be unnecessary, 7523 12105 1701 TAD @IDERDR ; get the IDE register address 7524 12106 2301 ISZ IDERDR ; (and don't forget to skip it!) 7525 12107 6476 PWPC ; send it to the drive via port C 7526 12110 1373 TAD [SETDRD] ; assert DIOR 7527 12111 6477 PWCR ; ... 7528 12112 7000 NOP ; give the drive and 8255 time to settle 7529 12113 6471 PRPB ; capture D0..D7 7530 12114 0362 AND [377] ; make sure we don't get noise in DX0..DX3 7531 12115 3322 DCA IDETMP ; and save that for a minute 7532 12116 1361 TAD [CLRDRD] ; now deassert DIOR 7533 12117 6477 PWCR ; ... 7534 12120 1322 TAD IDETMP ; get the data back 7535 12121 5701 JMP @IDERDR ; and return it in the AC 7536 7537 ; Local storage for RD/IDEWRR... 7538 12122 IDETMP: .BLOCK 1 ; a temporary for saving the AC 7539 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 188 Setup Disk I/O Buffer BTS6120.PLX 7540 .TITLE Setup Disk I/O Buffer 7541 7542 7543 ; This routine is used parse the argument list for ROM calls that take OS/8 7544 ; handler like argument lists, primarily the RAM disk and IDE disk I/O calls. 7545 ; It will do a GETARG and store the first argument, which contains the R/W 7546 ; bit, page count, buffer field and unit number, in MUUO. It extracts the 7547 ; buffer field from this argument, builds a CDF instruction, and stores that 7548 ; at BUFCDF for later use. It also extracts the page count from this 7549 ; argument, converts it to a negative number, and stores the result at RWCNT. 7550 ; Finally, it does another GETARG to fetch the address of the caller's buffer 7551 ; and stores that at BUFPTR. 7552 12123 6205 SETBUF: .PUSHJ @[GETARG] ; get the first argument 12124 5777 7553 12125 3047 DCA MUUO ; save that - it's got lots of useful bits! 7554 12126 1047 TAD MUUO ; get the field bits from MUUO 7555 12127 0360 AND [70] ; ... 7556 12130 1357 TAD [CDF 0] ; make a CDF instruction out of them 7557 12131 3756 DCA @[BUFCDF+1] ; and save them for later 7558 12132 1047 TAD MUUO ; get the page count from the call 7559 12133 0355 AND [3700] ; ... 7560 12134 7450 SNA ; is it zero ? 7561 12135 7330 NL4000 ; yes - that means to transfer a full 32 pages 7562 12136 7002 BSW ; right justify the page count 7563 12137 7041 CIA ; make it negative for an ISZ 7564 12140 3054 DCA RWCNT ; ... 7565 12141 6205 .PUSHJ @[GETARG] ; get the buffer pointer from the argument list 12142 5777 7566 12143 1354 TAD [-1] ; correct for pre-incrementing auto-index 7567 12144 3011 DCA BUFPTR ; and save that 7568 12145 3052 DCA BUFPNL ; this buffer is always in main memory 7569 12146 6225 .POPJ ; all done for now 7570 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 7571 12200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 189 Setup Disk I/O Buffer Field and Space BTS6120.PLX 7572 .TITLE Setup Disk I/O Buffer Field and Space 7573 7574 7575 ; This routine will set up BUFPTR, BUFCDF, RWCNT and BUFPNL to point to 7576 ; our own internal buffer in panel memory at DSKBUF. This is used by the 7577 ; disk dump, disk load, format and boot commands when they need to read or 7578 ; write disk blocks without distrubing main memory. 7579 12200 1377 PNLBUF: TAD [DSKBUF-1] ; point to the disk buffer 7580 12201 3011 DCA BUFPTR ; set the buffer address for DISKRD/DISKWR 7581 12202 1376 TAD [CDF 1] ; this buffer lives in our field 1 7582 12203 3212 DCA BUFCDF+1 ; ... 7583 12204 7344 NLM2 ; the buffer size is always 2 pages 7584 12205 3054 DCA RWCNT ; ... 7585 12206 7240 NL7777 ; write this data to PANEL memory! 7586 12207 3052 DCA BUFPNL ; ... 7587 12210 6225 .POPJ ; and we're done 7588 7589 7590 ; This little routine is called, via a JMS instruction (not a .PUSHJ!) to 7591 ; change the DF to the field of the user's buffer. In addition, if the 7592 ; BUFPNL flag is not set, it will execute a CPD instruction so that buffer 7593 ; data is stored in main memory. This is the usual case. 7594 12211 0000 BUFCDF: 0 ; call here with a JMS 7595 12212 7000 NOP ; gets over written with a CDF instruction 7596 12213 7200 CLA ; just in case 7597 12214 1052 TAD BUFPNL ; is the panel buffer flag set? 7598 12215 7650 SNA CLA ; ??? 7599 12216 6266 CPD ; no - address main memory now 7600 12217 5611 JMP @BUFCDF ; ... 7601 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 190 Copy Memory ROM Calls BTS6120.PLX 7602 .TITLE Copy Memory ROM Calls 7603 7604 7605 ; This ROM function can copy up to 4096 words from any field in either main 7606 ; or panel memory to any other address and field in either main or panel 7607 ; memory. It can be used to move data and/or code into panel memory and 7608 ; back again, or simply to move one part of main memory to another. 7609 ; 7610 ;CALL: 7611 ; PR0 7612 ; 0010 / copy memory subfunction 7613 ; p0n0 / source field and memory space 7614 ;
/ source address 7615 ; p0n0 / destination field and memory space 7616 ;
/ destination address 7617 ; / number of words to be transferred 7618 ; 7619 ; The source and destination field words each contain the field number in 7620 ; bits 6..8, and a flag in bit 0 which is one for panel memory and zero for 7621 ; main memory. The last word of the argument list is the number of words 7622 ; to be copied - a value of zero copies 4096 words. 7623 7624 ; Set up the source address... 7625 12220 6205 MEMMOV: .PUSHJ @[GETARG] ; get the source field 12221 5775 7626 12222 7100 CLL ; make sure the link is in a known state 7627 12223 1374 TAD [4000] ; put the panel/main memory flag in the LINK 7628 12224 0373 AND [70] ; make a CDF instruction 7629 12225 1372 TAD [CDF 0] ; ... 7630 12226 3262 DCA SRCCDF ; ... 7631 12227 1371 TAD [CPD] ; assume the source is in main memory 7632 12230 7430 SZL ; but is it really ? 7633 12231 1370 TAD [SPD-CPD] ; no - use panel memory 7634 12232 3263 DCA SRCSPD ; ... 7635 12233 6205 .PUSHJ @[GETARG] ; get the buffer address 12234 5775 7636 12235 1367 TAD [-1] ; correct for pre-increment auto index 7637 12236 3012 DCA XX1 ; ... 7638 7639 ; Set up the destination address... 7640 12237 6205 .PUSHJ @[GETARG] ; get the destination field 12240 5775 7641 12241 7100 CLL ; make sure the link is in a known state 7642 12242 1374 TAD [4000] ; put the panel/main memory flag in the LINK 7643 12243 0373 AND [70] ; make a CDF instruction 7644 12244 1372 TAD [CDF 0] ; ... 7645 12245 3265 DCA DSTCDF ; ... 7646 12246 1371 TAD [CPD] ; assume the destination is in main memory 7647 12247 7430 SZL ; but is it really ? 7648 12250 1370 TAD [SPD-CPD] ; no - use panel memory 7649 12251 3266 DCA DSTSPD ; ... 7650 12252 6205 .PUSHJ @[GETARG] ; get the buffer address 12253 5775 7651 12254 1367 TAD [-1] ; correct for pre-increment auto index 7652 12255 3013 DCA XX2 ; ... 7653 7654 ; And finally the word count... 7655 12256 6205 .PUSHJ @[GETARG] ; ... 12257 5775 7656 12260 7041 CIA ; make it negative for ISZ 7657 12261 3051 DCA XFRCNT ; ... 7658 7659 ; This loop does the actual work of copying data! 7660 12262 7000 SRCCDF: NOP ; over written with a CDF instruction 7661 12263 7000 SRCSPD: NOP ; over written with a SPD/CPD IOT PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 191 Copy Memory ROM Calls BTS6120.PLX 7662 12264 1412 TAD @XX1 ; get a word of source data 7663 12265 7000 DSTCDF: NOP ; over written with a CDF instruction 7664 12266 7000 DSTSPD: NOP ; overwritten with a SPD/CPD IOT 7665 12267 3413 DCA @XX2 ; and store the word 7666 12270 2051 ISZ XFRCNT ; have we done them all ? 7667 12271 5262 JMP SRCCDF ; no - keep copying 7668 7669 ; All done! 7670 12272 6276 SPD ; be sure the field and memory space are safe 7671 12273 6211 CDF 1 ; ... 7672 12274 7300 CLL CLA ; and always return success 7673 12275 6225 .POPJ ; ... 7674 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 192 Copy Memory Extended ROM Call BTS6120.PLX 7675 .TITLE Copy Memory Extended ROM Call 7676 7677 7678 ; This ROM function can copy up to 4096 words from any field in main, panel 7679 ; or ramdisk memory to any other field in main, panel or ramdisk memory. 7680 ; 7681 ;CALL: 7682 ; PR0 7683 ; 0011 / copy memory subfunction 7684 ; pddf / source DAR, field and memory space 7685 ; pddf / destination DAR, field and memory space 7686 ;
/ source address 7687 ;
/ destination address 7688 ; / number of words to be transferred 7689 ; 7690 ; The source and destination field words (pddf) each contain a flag 7691 ; in bit 0, the ramdisk Disk Address in bits 1..8 (or a flag in bit 1), 7692 ; and the field number in bits 9..11 7693 ; 7694 ; The flags are interpreted as 7695 ; bit 0 = 1 when the address is in the ramdisk, otherwise 7696 ; bit 1 = 1 when the address is in panel memory, otherwise 7697 ; the address is in main memory 7698 ; The last word of the argument list is the number of words 7699 ; to be copied - a value of zero copies 4096 words. 7700 7701 0024 SRCDAR=RDUNIT 7702 0025 DSTDAR=RDPAGE 7703 7704 12276 7200 MEMMVX: CLA ; set up source addressing 7705 12277 1366 TAD [XSRCDF-1] 7706 12300 4765 JMS @[MVXARG] 7707 12301 3024 DCA SRCDAR 7708 7709 12302 1364 TAD [XDSCDF-1] ; set up destination addressing 7710 12303 4765 JMS @[MVXARG] 7711 12304 3025 DCA DSTDAR 7712 7713 12305 6205 .PUSHJ @[GETARG] ; get the source address 12306 5775 7714 12307 1367 TAD [-1] ; correct for pre-increment auto index 7715 12310 3012 DCA XX1 ; ... 7716 7717 12311 6205 .PUSHJ @[GETARG] ; get the destination address 12312 5775 7718 12313 1367 TAD [-1] ; correct for pre-increment auto index 7719 12314 3013 DCA XX2 ; ... 7720 7721 12315 6205 .PUSHJ @[GETARG] ; get the word count 12316 5775 7722 12317 7041 CIA ; make it negative for ISZ 7723 12320 3051 DCA XFRCNT ; ... 7724 7725 12321 7000 XSRCDF: NOP ; overwritten with a CDF instruction 7726 12322 7000 NOP ; overwritten with a SPD/CPD IOT 7727 12323 7000 NOP ; overwritten with a memory map IOT 7728 12324 1024 TAD SRCDAR ; set DAR to source DAR 7729 12325 6410 LDAR ; (leaves AC clr) 7730 12326 1412 TAD @XX1 ; get a word of source data 7731 12327 7421 MQL ; save in MQ 7732 12330 7000 XDSCDF: NOP ; overwritten with a CDF instruction 7733 12331 7000 NOP ; overwritten with a SPD/CPD IOT 7734 12332 7000 NOP ; overwritten by a memory map IOT 7735 12333 1025 TAD DSTDAR ; set DAR to destination DAR 7736 12334 6410 LDAR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 193 Copy Memory Extended ROM Call BTS6120.PLX 7737 12335 7521 SWP ; get back source value 7738 12336 3413 DCA @XX2 ; and store the word 7739 12337 2051 ISZ XFRCNT ; have we done them all ? 7740 12340 5321 JMP XSRCDF ; no - keep copying 7741 7742 ; All done! 7743 12341 6402 MM2 ; back to standard map 7744 12342 6276 SPD ; be sure the field and memory space are safe 7745 12343 6211 CDF 1 ; ... 7746 12344 7300 CLL CLA ; and always return success 7747 12345 6225 .POPJ ; ... 7748 12364 2327 12365 2400 12366 2320 12367 7777 12370 0010 12371 6266 12372 6201 12373 0070 12374 4000 12375 0241 12376 6211 12377 7377 7749 12400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 194 Get Arguments for MEMMOV Calls BTS6120.PLX 7750 .TITLE Get Arguments for MEMMOV Calls 7751 7752 7753 ; MVXARG: 7754 ; call: JMS MVXARG 7755 ; entry: AC points to CDF x, yPD, MMz sequence location 7756 ; function: get and interpret an addressing control argument, filling out @XX1 7757 ; exit: AC contains DAR value 7758 12400 0000 MVXARG: 0 7759 12401 3012 DCA XX1 ; Save pointer to modified code in auto-incr 7760 12402 6205 .PUSHJ @[GETARG] ; get the source field 12403 5777 7761 12404 7100 CLL ; make sure the link is in a known state 7762 12405 1376 TAD [4000] ; put the ramdisk/RAM flag in the LINK 7763 12406 7420 SNL 7764 12407 5226 JMP ADRPMM ; if b0=0, do panel/main memory addressing 7765 ; address is in ramdisk 7766 7767 12410 7014 ADRRMD: R3L ; rotate first two bits of DAR around to lsbs 7768 12411 7421 MQL ; save it; it has the field in the right position 7769 12412 7701 ACL ; get it back (AC was cleared by MQL) 7770 12413 7002 BSW ; rotate another 6 bits, AC now has DAR in b4..b11 7771 12414 7521 SWP ; save it, get back field 7772 12415 0375 AND [70] ; make a CDF instruction 7773 12416 1374 TAD [CDF 0] ; ... 7774 12417 3412 DCA @XX1 ; ... 7775 12420 1373 TAD [SPD] ; ramdisk DF must be panel 7776 12421 3412 DCA @XX1 7777 12422 1372 TAD [MM3] ; use memory map 3 (indirect panel access -> ramdisk) 7778 12423 3412 DCA @XX1 7779 12424 7521 SWP ; and return with DAR in AC 7780 12425 5600 JMP @MVXARG 7781 7782 ; address is in panel or main memory 7783 7784 12426 1371 ADRPMM: TAD [6000] ; know that b0=0, link=1; 7785 ; now link=0 if b1=1 7786 12427 7014 R3L ; bring field into position 7787 12430 0375 AND [70] ; make a CDF instruction 7788 12431 1374 TAD [CDF 0] ; ... 7789 12432 3412 DCA @XX1 ; ... 7790 12433 1370 TAD [CPD] ; assume the source is in main memory 7791 12434 7420 SNL ; but is it really ? 7792 12435 1367 TAD [SPD-CPD] ; no - use panel memory 7793 12436 3412 DCA @XX1 ; ... 7794 12437 1366 TAD [MM2] ; use memory map 2 (indirect access -> RAM) 7795 12440 3412 DCA @XX1 7796 12441 5600 JMP @MVXARG PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 195 LIGHTS Monitor Call BTS6120.PLX 7797 .TITLE LIGHTS Monitor Call 7798 7799 7800 ; The LIGHTS MUUO allows a program explicit control over the front panel 7801 ; DATA LEDs (providing a front panel is installed, of course!). It only 7802 ; works for the DATA LEDs - the ADDRESS LEDs always track the current memory 7803 ; address, and it only works _if_ the rotary switch is _not_ set to the MD 7804 ; position. 7805 ; 7806 ; The calling sequence for the LIGHTS MUUO is: 7807 ; 7808 ; TAD (data / desired data for the display 7809 ; PR0 / trap to panel memory 7810 ; 0012 / LIGHTS function code 7811 ; / 1 to put the DATA display under program control 7812 ; / 0 to return the display to normal use 7813 ; / if no display is present or is not 0 or 1, 7814 ; / then the LINK will be set on return. 7815 ; 7816 ; Note that a program can determine whether an FP6120 is present without 7817 ; changing anything simply by invoking the LIGHTS function with set 7818 ; to 0. If no display is present, the LINK will be set on return. 7819 ; 7820 12442 6205 LIGHTS: .PUSHJ @[GETARG] ; get the argument 12443 5777 7821 12444 7421 MQL ; save it for a second 7822 12445 6201 CDF 0 ; all panel data lives in field zero 7823 12446 1765 TAD @[FPDTCT] ; is a front panel installed?? 7824 12447 6211 CDF 1 ; back to our field 7825 12450 7120 STL ; assume not 7826 12451 7650 SNA CLA ; but skip if it is 7827 12452 6225 .POPJ ; no front panel - take the error return 7828 12453 7701 ACL ; get the function code again 7829 12454 7450 SNA ; is it zero? 7830 12455 5265 JMP LIGHT1 ; yes - go restore the lights 7831 12456 1364 TAD [-1] ; is it one? 7832 12457 7640 SZA CLA ; if it's more than 1 the LINK will be set 7833 12460 6225 .POPJ ; so take the error return 7834 7835 ; Here to switch the LEDs to program mode and display the data passed 7836 ; in the accumulator... 7837 12461 6201 CDF 0 ; all this data lives in field zero again 7838 12462 1763 TAD @[UAC] ; get the user's data 7839 12463 3762 DCA @[FPPGMD] ; save the program data 7840 12464 7240 STA ; and set the front panel program mode 7841 ; fall thru into the remaining code 7842 7843 ; Here to return the LEDs to normal operation.... 7844 12465 3761 LIGHT1: DCA @[FPPGMM] ; ... 7845 12466 6211 CDF 1 ; back to our field again 7846 12467 7300 CLA CLL ; and give the successful return 7847 12470 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 196 Field 1 Vector Table BTS6120.PLX 7848 .TITLE Field 1 Vector Table 7849 7850 7851 12471 6223 RET1F2: CXF 2 ; return to field 2 7852 12472 6225 .POPJ ; the address is already on the stack 7853 7854 12473 6233 RET1F3: CXF 3 ; return to field 3 7855 12474 6225 .POPJ ; the address is already on the stack 7856 7857 7858 ; variable and functions that we may want to access or hook in this field 7859 ; codes: I=instruction pointer, V=variable, H=hook (CIF n, JMP @.+1, V) 7860 ; Add only to the *end* of this list, please! 7861 ; n.b. JMS linkage functions generally cannot be used here 7862 12475 F1VECTOR: 7863 12475 2473 RET1F3 ; I utility - return to field 2 (must be first) 7864 12476 0261 FUNTBL ; V table of ROM functions 7865 12477 3200 CMDTBL ; V table of monitor commands 7866 12500 1213 DISKRD-1 ; H read IDE 7867 12501 1243 DISKWR-1 ; H write IDE 7868 12502 0000 0 7869 12503 0020 DKPART ; V partition number for DISKRD/WR 7870 12504 0021 DKRBN ; V block number for DISKRD/WR 7871 12505 0011 BUFPTR ; V offset for DISKRD/WR 7872 12506 2212 BUFCDF+1 ; V field for DISKRD/WR 7873 12507 0052 BUFPNL ; V memory space for DISKRD/WR 7874 12510 0022 DKSIZE ; V size of IDE attached drive, or 0 if none 7875 12561 0061 12562 0062 12563 0001 12564 7777 12565 0056 12566 6402 12567 0010 12570 6266 12571 6000 12572 6403 12573 6276 12574 6201 12575 0070 12576 4000 12577 0241 7876 12600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 197 Flash ROM erasure and writing BTS6120.PLX 7877 .TITLE Flash ROM erasure and writing 7878 7879 7880 ; write block to Flash ROM. Since Flash requires an erasure step, and we 7881 ; don't know how big the file will be, a slightly risky heuristic is used 7882 ; to determine when to issue an erase command. What it does is, whenever the 7883 ; current address is on a 4KB boundary, the next 4KB is scanned. If any bytes 7884 ; there are not 377, an erase command is issued. 4KB is convenient not just 7885 ; because of the PDP-8 pointer size, but because most if not all flash ROMs 7886 ; allocate blocks in multiples of this size (note that in a device blocks 7887 ; may vary in size). 7888 ; 7889 ; There are simple cases that will confuse this, but we will just have to 7890 ; specify that no 4KB block should be filled with 377s in a download image. 7891 ; 7892 ; The incoming data file must be in the Flash download format: 7893 ; byte data 7894 ; 256 words per block (therefore 256 bytes) 7895 ; starting at 0000 with monotonically increasing block numbers 7896 ; 7897 7898 ; N.b. there're a number of places in this routine where the fact that 7899 ; the ROM is in field 1 of the ramdisk memory while this code is in 7900 ; field 1 of the RAM is taken advantage of. 7901 7902 12600 3053 ROMWR: DCA BUFSIZ ; save the passed size (= -256) 7903 7904 12601 1021 TAD DKRBN ; DAR is set to the upper 8 bits of the 7905 12602 7012 RTR ; block number 7906 12603 7012 RTR 7907 12604 6410 LDAR 7908 7909 12605 6403 MM3 ; access the ramdisk area 7910 7911 12606 1377 TAD [FCMDCS] ; issue "clear status register" command 7912 12607 3400 DCA @0 7913 12610 1376 TAD [FCMDRA] ; issue "read array" command 7914 12611 3400 DCA @0 7915 7916 12612 1021 TAD DKRBN 7917 12613 0375 AND [17] ; check for multiple of 4KB (16*256) 7918 12614 7640 SZA CLA 7919 12615 5246 JMP NOERA 7920 7921 ; We're on a 4KB boundary, check the next 4KB for non-377 bytes 7922 7923 12616 3341 DCA NX1 ; starting at 0 7924 12617 1741 CHKERA: TAD @NX1 7925 12620 1374 TAD [-377] 7926 12621 7640 SZA CLA 7927 12622 5226 JMP ERABLK ; need to erase 7928 12623 2341 ISZ NX1 7929 12624 5217 JMP CHKERA 7930 12625 5246 JMP NOERA 7931 7932 ; Erase block. We don't know how far this erase will extend, but we will 7933 ; only erase again when we reach some unerased ROM, so it's not an issue. 7934 7935 12626 1373 ERABLK: TAD [FCMDERA1] ; issue "erase block 1" command 7936 12627 3400 DCA @0 7937 12630 1372 TAD [FCMDERA2] ; issue "erase block 2" command 7938 12631 3400 DCA @0 7939 12632 7200 WFRDY1: CLA ; get the status byte 7940 12633 1400 TAD @0 7941 12634 0371 AND [200] ; check the ready bit PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 198 Flash ROM erasure and writing BTS6120.PLX 7942 12635 7450 SNA 7943 12636 5232 JMP WFRDY1 ; no, not ready yet 7944 12637 7200 CLA 7945 12640 1400 TAD @0 ; get the status again to check for errors 7946 12641 0370 AND [177] 7947 12642 7450 SNA 7948 12643 5246 JMP NOERA 7949 12644 1367 TAD [1000] ; Error 1xxx - bad erase; xxx is status code 7950 12645 5336 JMP BADFL 7951 7952 ; now program the block 7953 7954 12646 1021 NOERA: TAD DKRBN ; form the offset by taking the lower 4 7955 12647 7002 BSW ; bits of the block number and using that 7956 12650 7006 RTL ; to address a 256-byte sector 7957 12651 0366 AND [7400] 7958 12652 3341 DCA NX1 ; destination address 7959 7960 12653 1365 TAD [DSKBUF-1] ; source buffer (field 1) 7961 12654 3012 DCA XX1 ; save in autoincr 7962 7963 12655 6403 PROGLP: MM3 7964 12656 1364 TAD [FCMDPROG] ; issue the write byte command 7965 12657 3741 DCA @NX1 7966 12660 6402 MM2 7967 12661 1412 TAD @XX1 7968 12662 6403 MM3 7969 12663 3741 DCA @NX1 ; and write it 7970 7971 12664 7200 WFRDY2: CLA ; get the status byte 7972 12665 1400 TAD @0 7973 12666 0371 AND [200] ; check the ready bit 7974 12667 7450 SNA 7975 12670 5264 JMP WFRDY2 ; no, not ready yet 7976 12671 7200 CLA 7977 12672 1400 TAD @0 ; b8=1, b6-b0=status bits 7978 12673 0370 AND [177] 7979 12674 7450 SNA 7980 12675 5300 JMP FLNXT 7981 12676 1363 TAD [2000] ; Error 2xxx - bad write; xxx is status code 7982 12677 5336 JMP BADFL 7983 7984 12700 2341 FLNXT: ISZ NX1 ; increment write address 7985 12701 7000 NOP ; may be at end of field 7986 7987 12702 2053 ISZ BUFSIZ ; done with block? 7988 12703 5255 JMP PROGLP ; no, write another byte 7989 7990 12704 1376 TAD [FCMDRA] ; flash back into read array mode 7991 12705 3400 DCA @0 7992 7993 ; now verify the data in ROM against the RAM buffer 7994 7995 12706 1365 TAD [DSKBUF-1] ; compare the disk buffer 7996 12707 3012 DCA XX1 7997 7998 12710 1341 TAD NX1 ; to the ROM, and 7999 12711 1365 TAD [-256.-1] 8000 12712 3013 DCA XX2 8001 8002 12713 1366 TAD [-256.] ; check 256 bytes 8003 12714 3053 DCA BUFSIZ 8004 12715 5316 JMP CHKLP 8005 8006 12716 6402 CHKLP: MM2 ; note that comparison will fail if PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 199 Flash ROM erasure and writing BTS6120.PLX 8007 12717 1412 TAD @XX1 ; data in DSKBUF has any of the upper 4 bits 8008 12720 7041 CIA ; set, since the ROM is an 8-bit device 8009 12721 6403 MM3 8010 12722 1413 TAD @XX2 8011 12723 7440 SZA 8012 12724 5332 JMP BADCHK 8013 12725 2053 ISZ BUFSIZ 8014 12726 5316 JMP CHKLP 8015 8016 12727 6402 MM2 8017 12730 7300 CLA CLL 8018 12731 6225 .POPJ 8019 8020 12732 7200 BADCHK: CLA 8021 12733 1013 TAD XX2 8022 12734 0362 AND [0777] ; Error 3xxx - compare mismatch; xxx is offs. 8023 12735 1361 TAD [3000] 8024 8025 12736 6402 BADFL: MM2 8026 12737 7120 STL 8027 12740 6225 .POPJ 8028 8029 ; Flash ROM routine storage.. 8030 12741 NX1: .BLOCK 1 8031 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 8032 13000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 200 Free Space for Future Expansion! BTS6120.PLX 8033 .TITLE Free Space for Future Expansion! 8034 8035 ; space to put any patch code for this field 8036 13000 F1PATCH: 8037 8038 13200 .PAGE 15 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 201 Command Names Table BTS6120.PLX 8039 .TITLE Command Names Table 8040 8041 8042 ; This table gives the names of all the commands known to the monitor. Each 8043 ; entry consists of a one or two letter command name, in SIXBIT, followed by 8044 ; the address of a routine to execute it. Although this table is stored in 8045 ; field 1, all the command routines are implicitly in field zero! The zero 8046 ; entry at the end is a "catch all" that is called if none of the previous 8047 ; names match, and points to an error routine. With the exception of this last 8048 ; entry, the order of the table is not significant. 8049 13200 CMDTBL: 8050 13200 .SIXBIT /H / ; Help 8051 13201 0736 HELP ; ... 8052 13202 .SIXBIT /RP/ ; RePeat 8053 13203 0600 REPEAT ; ... 8054 13204 .SIXBIT /E / ; Examine 8055 13205 1002 EMEM ; ... 8056 13206 .SIXBIT /EP/ ; Examine Panel memory 8057 13207 1000 EPMEM ; ... 8058 13210 .SIXBIT /D / ; Deposit 8059 13211 1067 DMEM ; ... 8060 13212 .SIXBIT /DP/ ; Deposit Panel memory 8061 13213 1065 DPMEM ; ... 8062 13214 .SIXBIT /ER/ ; Examine Register 8063 13215 1114 EREG ; ... 8064 13216 .SIXBIT /DR/ ; Deposit Register 8065 13217 1132 DREG ; ... 8066 13220 .SIXBIT /BM/ ; Block Move 8067 13221 1400 BMOVE ; ... 8068 13222 .SIXBIT /CK/ ; ChecKsum 8069 13223 1442 CKMEM ; ... 8070 13224 .SIXBIT /WS/ ; Word Search 8071 13225 1600 SEARCH ; ... 8072 13226 .SIXBIT /CM/ ; Clear Memory 8073 13227 1507 CMEM ; ... 8074 13230 .SIXBIT /FM/ ; Fill Memory 8075 13231 1503 FLMEM ; ... 8076 13232 .SIXBIT /BL/ ; Breakpoint List 8077 13233 1674 BLIST ; ... 8078 13234 .SIXBIT /BP/ ; BreakPoint 8079 13235 2036 BPTCOM ; ... 8080 13236 .SIXBIT /BR/ ; Breakpoint Remove 8081 13237 2000 BREMOV ; ... 8082 13240 .SIXBIT /C / ; Continue 8083 13241 2214 CONTCM ; ... 8084 13242 .SIXBIT /SI/ ; Single Instruction with no trace 8085 13243 2200 SNCOM ; ... 8086 13244 .SIXBIT /ST/ ; STart 8087 13245 2251 START ; ... 8088 13246 .SIXBIT /P / ; Proceed 8089 13247 2207 PROCEE ; ... 8090 13250 .SIXBIT /TR/ ; single instruction with TRace 8091 13251 2144 SICOM ; ... 8092 13252 .SIXBIT /VE/ ; VErsion (of monitor) 8093 13253 0677 VECOM ; ... 8094 13254 .SIXBIT /TW/ ; Terminal Width 8095 13255 0625 TWCOM ; ... 8096 13256 .SIXBIT /TP/ ; Terminal Page 8097 13257 0650 TPCOM ; ... 8098 13260 .SIXBIT /EX/ ; EXECUTE (IOT instruction) 8099 13261 2324 XCTCOM ; ... 8100 13262 .SIXBIT /MR/ ; MASTER RESET 8101 13263 2300 CLRCOM ; ... 8102 13264 .SIXBIT /LP/ ; LOAD PAPER (tape from console) 8103 13265 3200 CONLOD ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 202 Command Names Table BTS6120.PLX 8104 13266 .SIXBIT /DD/ ; Disk (IDE) Dump 8105 13267 3405 DDDUMP ; ... 8106 13270 .SIXBIT /RD/ ; Disk (RAM) Dump 8107 13271 3400 RDDUMP ; ... 8108 13272 .SIXBIT /DL/ ; Disk (IDE) Load 8109 13273 3520 DLLOAD ; ... 8110 13274 .SIXBIT /RL/ ; Disk (RAM) Load 8111 13275 3513 RLLOAD ; ... 8112 13276 .SIXBIT /DF/ ; Disk (IDE) Format 8113 13277 3072 DFRMAT ; ... 8114 13300 .SIXBIT /RF/ ; Disk (RAM) Format 8115 13301 3120 RFRMAT 8116 13302 .SIXBIT /B / ; Bootstrap ram disk 8117 13303 2426 BOOT 8118 13304 .SIXBIT /PM/ ; Partition Map 8119 13305 2600 PMEDIT ; ... 8120 13306 .SIXBIT /PC/ ; Partition Copy 8121 13307 4022 PCOPY ; ... 8122 13310 .SIXBIT /FL/ ; Flash Load 8123 13311 4213 FLLOAD 8124 13312 .SIXBIT /PE/ ; Partition Compare 8125 13313 4013 PCOMP ; ... 8126 13314 .SIXBIT /X / ; Disassemble Main Memory 8127 13315 1546 DISASM ; ... 8128 13316 .SIXBIT /XP/ ; Disassemble Panel Memory 8129 13317 1550 DISASMP ; ... 8130 13320 .SIXBIT /SC/ ; SCope 8131 13321 0670 SCCOM 8132 8133 ; there are 9 copies of the end-of-command list sentinel here so that 8134 ; up to 8 commands may be added by an extension ROM 8135 13322 0000 0000 ; This must always be the last entry 8136 13323 0453 COMERR ; Where to go if none of the above matches 8137 13324 0000 0000 ; This must always be the last entry 8138 13325 0453 COMERR ; Where to go if none of the above matches 8139 13326 0000 0000 ; This must always be the last entry 8140 13327 0453 COMERR ; Where to go if none of the above matches 8141 13330 0000 0000 ; This must always be the last entry 8142 13331 0453 COMERR ; Where to go if none of the above matches 8143 13332 0000 0000 ; This must always be the last entry 8144 13333 0453 COMERR ; Where to go if none of the above matches 8145 13334 0000 0000 ; This must always be the last entry 8146 13335 0453 COMERR ; Where to go if none of the above matches 8147 13336 0000 0000 ; This must always be the last entry 8148 13337 0453 COMERR ; Where to go if none of the above matches 8149 13340 0000 0000 ; This must always be the last entry 8150 13341 0453 COMERR ; Where to go if none of the above matches 8151 13342 0000 0000 ; This must always be the last entry 8152 13343 0453 COMERR ; Where to go if none of the above matches PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 203 Argument Tables for Various Commands BTS6120.PLX 8153 .TITLE Argument Tables for Various Commands 8154 8155 8156 ; This table gives a list of the legal register names for the ER (Examine 8157 ; Register) command... 8158 13344 ENAMES: .SIXBIT /AC/ ; The AC 8159 13345 1252 TYPEAC 8160 13346 .SIXBIT /PC/ ; The PC 8161 13347 1255 TYPEPC 8162 13350 .SIXBIT /MQ/ ; The MQ 8163 13351 1260 TYPEMQ 8164 13352 .SIXBIT /PS/ ; The processor status 8165 13353 1265 TYPEPS 8166 13354 .SIXBIT /SR/ ; The switch register 8167 13355 1276 TYPESR 8168 13356 0000 0000 ; None of the above 8169 13357 0453 COMERR 8170 8171 ; This table gives a list of the legal register names for the DR (deposit 8172 ; register) command... 8173 13360 DNAMES: .SIXBIT /AC/ ; The AC 8174 13361 1200 DAC 8175 13362 .SIXBIT /PC/ ; The PC 8176 13363 1203 DPC 8177 13364 .SIXBIT /MQ/ ; The MQ 8178 13365 1206 DMQ 8179 13366 .SIXBIT /PS/ ; The flags 8180 13367 1211 DPS 8181 13370 .SIXBIT /SR/ ; The switch register 8182 13371 1221 DSR 8183 13372 0000 0000 ; None of the above 8184 13373 0453 COMERR 8185 8186 ; This table is a list of the arguments to the B (BOOT) command... 8187 13374 BNAMES: .SIXBIT /VM/ ; VMA0 8188 13375 2464 BTVMA0 8189 13376 .SIXBIT /ID/ ; IDA0 8190 13377 2500 BTIDA0 8191 13400 0000 0000 ; end of list 8192 13401 0453 COMERR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 204 Messages BTS6120.PLX 8193 .TITLE Messages 8194 8195 ; General purpose messages... 8196 13402 CKSMSG: .TEXT /Checksum = / 8197 13413 MEMMSG: .TEXT /?Memory error at / 8198 13430 ERRILV: .TEXT /Illegal value/ 8199 13442 ERRSRF: .TEXT /Search fails/ 8200 13453 ERRRAN: .TEXT /Wrong order/ 8201 13464 ERRWRP: .TEXT /Wrap around/ 8202 13475 SKPMSG: .TEXT /Skip / 8203 13502 ERRDIO: .TEXT \?I/O Error \ 8204 13513 ERRCKS: .TEXT /Checksum error/ 8205 13526 ERRNBT: .TEXT /No bootstrap/ 8206 13537 ERRNDK: .TEXT /No disk/ 8207 8208 ; Program trap messages... 8209 13545 BPTMSG: .TEXT /%Breakpoint at / 8210 13560 PR0MSG: .TEXT /?Illegal PR0 function at / 8211 13602 BRKMSG: .TEXT /%Break at / 8212 13612 PRNMSG: .TEXT /?Panel trap at / 8213 13625 HLTMSG: .TEXT /?Halted at / 8214 13636 TRPMSG: .TEXT /?Unknown trap at / 8215 8216 ; Breakpoint messages... 8217 13653 ERRNBP: .TEXT /None set/ 8218 13662 ERRNST: .TEXT /Not set/ 8219 13670 ERRAST: .TEXT /Already set/ 8220 13701 ERRBTF: .TEXT /Table full/ 8221 8222 ; Register names... 8223 13711 ACNAME: .TEXT /AC>/ 8224 13714 PCNAME: .TEXT /PC>/ 8225 13717 MQNAME: .TEXT /MQ>/ 8226 13722 IRNAME: .TEXT /IR>/ 8227 13725 SRNAME: .TEXT /SR>/ 8228 13730 PSNAME: .TEXT /PS>/ 8229 13733 SP1NAM: .TEXT /SP1>/ 8230 13737 SP2NAM: .TEXT /SP2>/ 8231 8232 ; Disk formatting status messages... 8233 13743 FCFMSG: .TEXT \Format unit/partition \ 8234 13763 FM1MSG: .TEXT /Writing / 8235 13772 FM2MSG: .TEXT / Verifying / 8236 14003 FM3MSG: .TEXT / Done/ 8237 14010 ERRDSK: .TEXT \?Verification error, block/page \ 8238 8239 ; Partition copy messages.... 8240 14037 CCFMSG: .TEXT \Overwrite partition \ 8241 14056 CP1MSG: .TEXT /Copying / 8242 4003 CP2MSG=FM3MSG 8243 8244 ; Partition compare messages.... 8245 3772 CE1MSG=FM2MSG 8246 4010 CEEMSG=ERRDSK 8247 8248 ; Partition map messages... 8249 14065 PM1MSG: .TEXT /Unit / 8250 14072 PM2MSG: .TEXT / -> Partition / 8251 8252 ; Device names that get printed by the boot sniffer... 8253 14105 VMAMSG: .TEXT /-VMA0/ 8254 14112 IDAMSG: .TEXT /-IDA0/ 8255 8256 ; System name message... 8257 14117 SYSNM1: .TEXT /SBC6120 ROM Monitor V/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 205 Messages BTS6120.PLX 8258 14136 SYSNM2: .TEXT / Checksum / 8259 14146 SYSNM3: .TEXT / \d \h/ 8260 14164 SYSCRN: .TEXT /Copyright (C) 1983-2003 Spare Time Gizmos. All rights reserved./ 8261 8262 ; RAM disk status message... 8263 14240 RAMMS1: .TEXT /NVR: / 8264 14245 RAMMS3: .TEXT /KB/ 8265 14250 BOKMSG: .TEXT / - Battery OK/ 8266 14262 BFAMSG: .TEXT / - Battery FAIL/ 8267 8268 ; IDE disk status message... 8269 14275 IDEMS1: .TEXT /IDE: / 8270 14302 IDEMS2: .TEXT /MB - / 8271 14307 IDEMS3: .TEXT /Not detected/ 8272 14320 IDEMS4: .TEXT /Not supported/ 8273 8274 ; Extension ROM messages 8275 14332 XRMES1: .TEXT /ROM: Error / 8276 8277 ; Flash messages 8278 14343 FLMSG1: .TEXT /?No Flash/ 8279 14352 FLMSG2: .TEXT /Overwrite flash/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 206 Help Text BTS6120.PLX 8280 .TITLE Help Text 8281 8282 8283 ; This table is used by the HELP command to generate a page of text 8284 ; describing the monitor commands. Each word is a pointer to a text string, 8285 ; also in field 1, which contains a single line of text, usually a description 8286 ; of one command. The table ends with a zero word. 8287 14365 HLPLST: 8288 ; Examine/Deposit commands... 8289 .DATA HLPEDC 14365 4465 8290 .DATA HLPE, HLPEP, HLPER, HLPX, HLPXP 14366 4511 14367 4553 14370 4616 14371 4643 14372 4702 8291 .DATA HLPD, HLPDP, HLPDR 14373 4741 14374 5005 14375 5052 8292 ; Memory commands... 8293 .DATA HLPNUL, HLPMEM 14376 4464 14377 5103 8294 .DATA HLPBM, HLPCK, HLPWS, HLPFM, HLPCM 14400 5116 14401 5153 14402 5210 14403 5247 14404 5301 8295 ; Breakpoint commands... 8296 .DATA HLPNUL, HLPBPC 14405 4464 14406 5330 8297 .DATA HLPBP, HLPBR, HLPBL, HLPP 14407 5346 14410 5372 14411 5421 14412 5443 8298 ; Program control commands... 8299 .DATA HLPNUL, HLPPCC 14413 4464 14414 5471 8300 .DATA HLPST, HLPC, HLPSI, HLPTR, HLPEX, HLPMR 14415 5512 14416 5547 14417 5572 14420 5615 14421 5642 14422 5676 8301 ; Disk commands... 8302 .DATA HLPNUL, HLPDSK 14423 4464 14424 5715 8303 .DATA HLPLP, HLPRD, HLPRL, HLPRF, HLPDD, HLPDL, HLPDF 14425 5727 14426 5754 14427 6011 14430 6035 14431 6060 14432 6117 14433 6145 8304 .DATA HLPPC, HLPPE, HLPFL, HLPPM, HLPB 14434 6235 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 207 Help Text BTS6120.PLX 14435 6274 14436 6343 14437 6172 14440 6366 8305 ; Other (miscellaneous) commands... 8306 .DATA HLPNUL, HLPMSC 14441 4464 14442 6416 8307 .DATA HLPTW, HLPTP, HLPSC, HLPVE, HLPSEM, HLPRP, HLPDOL 14443 6436 14444 6465 14445 6520 14446 6553 14447 6600 14450 6641 14451 6703 8308 ; Special control characters... 8309 .DATA HLPNUL, HLPCTL 14452 4464 14453 6730 8310 .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 8311 HLPNUL: .DATA 0 14464 0000 8312 8313 ; Examine/Deposit commands... 8314 14465 HLPEDC: .TEXT /EXAMINE AND DEPOSIT COMMANDS/ 8315 14511 HLPE: .TEXT /E aaaaa[-bbbbb] [, ccccc]\t-> Examine main memory/ 8316 14553 HLPEP: .TEXT /EP aaaaa[-bbbbb] [, ccccc]\t-> Examine panel memory/ 8317 14616 HLPER: .TEXT /ER [rr]\t\t\t\t-> Examine register/ 8318 14643 HLPX: .TEXT /X aaaaa[-bbbbb]\t\t-> Disassemble main memory/ 8319 14702 HLPXP: .TEXT /XP aaaaa[-bbbbb]\t\t-> Disassemble panel memory/ 8320 14741 HLPD: .TEXT /D aaaaa bbbb, [cccc, ...]\t-> Deposit in main memory/ 8321 15005 HLPDP: .TEXT /DP aaaaa bbbb, [cccc, ...]\t-> Deposit in panel memory/ 8322 15052 HLPDR: .TEXT /DR xx yyyy\t\t\t-> Deposit in register/ 8323 8324 ; Memory commands... 8325 15103 HLPMEM: .TEXT /MEMORY COMMANDS/ 8326 15116 HLPBM: .TEXT /BM aaaaa-bbbbb ddddd\t\t-> Move memory block/ 8327 15153 HLPCK: .TEXT /CK aaaaa-bbbbb\t\t\t-> Checksum memory block/ 8328 15210 HLPWS: .TEXT /WS vvvv [aaaaa-bbbbb [mmmm]]\t-> Search memory/ 8329 15247 HLPFM: .TEXT /FM vvvv [aaaaa-bbbbb]\t\t-> Fill memory/ 8330 15301 HLPCM: .TEXT /CM [aaaaa-bbbbb]\t\t-> Clear memory/ 8331 8332 ; Breakpoint commands... 8333 15330 HLPBPC: .TEXT /BREAKPOINT COMMANDS/ 8334 15346 HLPBP: .TEXT /BP aaaaa\t\t\t-> Set breakpoint/ 8335 15372 HLPBR: .TEXT /BR [aaaaa]\t\t\t-> Remove breakpoint/ 8336 15421 HLPBL: .TEXT /BL\t\t\t\t-> List breakpoints/ 8337 15443 HLPP: .TEXT /P\t\t\t\t-> Proceed past breakpoint/ 8338 8339 ; Program control commands... 8340 15471 HLPPCC: .TEXT /PROGRAM CONTROL COMMANDS/ 8341 15512 HLPST: .TEXT /ST [aaaaa]\t\t\t-> Start main memory program/ 8342 15547 HLPC: .TEXT /C\t\t\t\t-> Continue execution/ 8343 15572 HLPSI: .TEXT /SI\t\t\t\t-> Single instruction/ 8344 15615 HLPTR: .TEXT /TR\t\t\t\t-> Trace one instruction/ 8345 15642 HLPEX: .TEXT /EX 6xxx\t\t\t\t-> Execute an IOT instruction/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 208 Help Text BTS6120.PLX 8346 15676 HLPMR: .TEXT /MR\t\t\t\t-> Master reset/ 8347 8348 ; Disk commands... 8349 15715 HLPDSK: .TEXT /DISK COMMANDS/ 8350 15727 HLPLP: .TEXT /LB\t\t\t\t-> Load a BIN paper tape/ 8351 15754 HLPRD: .TEXT /RD u [pppp [cccc]]\t\t-> Dump RAM disk page/ 8352 16011 HLPRL: .TEXT /RL u\t\t\t\t-> Download RAM disk/ 8353 16035 HLPRF: .TEXT /RF u\t\t\t\t-> Format RAM disk/ 8354 16060 HLPDD: .TEXT /DD pppp [bbbb [cccc]]\t\t-> Dump IDE disk block/ 8355 16117 HLPDL: .TEXT /DL pppp\t\t\t\t-> Download IDE disk/ 8356 16145 HLPDF: .TEXT /DF pppp\t\t\t\t-> Format IDE disk/ 8357 16172 HLPPM: .TEXT /PM [u] [pppp]\t\t\t-> Edit or review IDE partition map/ 8358 16235 HLPPC: .TEXT /PC ssss dddd\t\t\t-> Copy partition ssss to dddd/ 8359 16274 HLPPE: .TEXT /PE aaaa bbbb\t\t\t-> Compare (Equal) partition aaaa to bbbb/ 8360 16343 HLPFL: .TEXT /FL\t\t\t\t-> Download Flash ROM/ 8361 16366 HLPB: .TEXT /B [dd]\t\t\t\t-> Boot RAM or IDE disk / 8362 8363 ; Other (miscellaneous) commands... 8364 16416 HLPMSC: .TEXT /MISCELLANEOUS COMMANDS/ 8365 16436 HLPTW: .TEXT /TW nn\t\t\t\t-> Set the console width/ 8366 16465 HLPTP: .TEXT /TP nn\t\t\t\t-> Set the console page length/ 8367 16520 HLPSC: .TEXT /SC n\t\t\t\t-> Set console scope on or off/ 8368 16553 HLPVE: .TEXT /VE\t\t\t\t-> Show firmware version/ 8369 16600 HLPSEM: .TEXT /aa; bb; cc; dd ...\t\t-> Combine multiple commands/ 8370 16641 HLPRP: .TEXT /RP [nn]; A; B; C; ...\t\t-> Repeat commands A, B, C/ 8371 16703 HLPDOL: .TEXT /!any text...\t\t\t-> Comment text/ 8372 8373 ; Special control characters... 8374 16730 HLPCTL: .TEXT /SPECIAL CHARACTERS/ 8375 16745 HLPCTS: .TEXT /Control-S (XOFF)\t\t-> Suspend terminal output/ 8376 17004 HLPCTQ: .TEXT /Control-Q (XON)\t\t\t-> Resume terminal output/ 8377 17042 HLPCTO: .TEXT /Control-O\t\t\t-> Suppress terminal output/ 8378 17075 HLPCTC: .TEXT /Control-C\t\t\t-> Abort current operation/ 8379 17130 HLPCTH: .TEXT /Control-H (Backspace)\t\t-> Delete the last character entered/ 8380 17201 HLPRUB: .TEXT /RUBOUT (Delete)\t\t\t-> Delete the last character entered/ 8381 17246 HLPCTR: .TEXT /Control-R\t\t\t-> Retype the current line/ 8382 17301 HLPCTU: .TEXT /Control-U\t\t\t-> Erase current line/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 209 Temporary Disk Buffer BTS6120.PLX 8383 .TITLE Temporary Disk Buffer 8384 8385 8386 ; The last two pages of field 1, addresses 17400 thru 17777, are used as a 8387 ; temporary disk buffer by the disk load, disk dump, disk format and boot 8388 ; commands. 8389 17400 .PAGE 36 8390 17400 DSKBUF: .BLOCK 128. 8391 17600 .PAGE 37 8392 17600 .BLOCK 128. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 210 Field 2 Variables BTS6120.PLX 8393 .TITLE Field 2 Variables 8394 8395 8396 20200 .FIELD 2 8397 20000 .PAGE 0 8398 8399 20000 MNEMP: .BLOCK 1 ; address of last mnemonic output 8400 20001 MEA: .BLOCK 1 ; effective address 8401 20002 MIA: .BLOCK 1 ; indirect address 8402 20003 XPC: .BLOCK 1 ; Program Counter 8403 20004 XIR: .BLOCK 1 ; Instruction Register 8404 20005 IFDF: .BLOCK 1 8405 20006 DPNL: .BLOCK 1 8406 8407 20010 .ORG 10 8408 20010 SCAN: .BLOCK 1 ; auto-incr ptr to OPJMP table 8409 20011 ASCAN: .BLOCK 1 ; auto-incr ptr to mnemonic table 8410 20012 MPTR: .BLOCK 1 ; auto-incr ptr for TASZF2 8411 20013 AX1: .BLOCK 1 8412 20014 AX2: .BLOCK 1 8413 8414 20020 .ORG 20 8415 8416 20020 PUSHAC2: .BLOCK 1 8417 20021 DESTA: .BLOCK 1 8418 8419 20100 .ORG 100 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 211 Field 2 Cross Field Linkages BTS6120.PLX 8420 .TITLE Field 2 Cross Field Linkages 8421 8422 8423 ; This two routines will allow a routine in field 2 to simulate a .PUSHJ 8424 ; to a routines in field 0 or 1. The contents of the AC are preserved both 8425 ; ways across the call. 8426 ; 8427 ;CALL: 8428 ; JMS PJ0F2 or PJ1F2 ; cross field call "PUSHJ to 0 From 2" 8429 ; ; address of a routine in field 1 8430 ; ; with the AC preserved across the call 8431 ; 8432 20100 0000 PJ0F2: 0 ; call here with a JMS instruction 8433 20101 3020 DCA PUSHAC2 ; save the caller's AC for a minute 8434 20102 6221 CDF 2 8435 20103 1500 TAD @PJ0F2 ; then get caller's argument 8436 20104 3021 DCA DESTA ; that's the address of the routine to call 8437 20105 1100 TAD PJ0F2 ; now get caller's return address 8438 20106 7001 IAC ; and skip over the argument 8439 20107 6215 .PUSH ; put that on the stack 8440 20110 7200 CLA ; (PUSH doesn't clear the AC!) 8441 20111 1177 TAD [RET0F2] ; the field 0 routine will return to 8442 20112 6215 .PUSH ; ... 8443 20113 7200 CLA ; ... 8444 20114 1020 TAD PUSHAC2 ; restore the original AC contents 8445 20115 6203 CXF 0 ; call with IF = DF = 0 8446 20116 5421 JMP @DESTA ; and go to the code in field 0 8447 8448 20117 0000 PJ1F2: 0 ; call here with a JMS instruction 8449 20120 3020 DCA PUSHAC2 ; save the caller's AC for a minute 8450 20121 6221 CDF 2 8451 20122 1517 TAD @PJ1F2 ; then get caller's argument 8452 20123 3021 DCA DESTA ; that's the address of the routine to call 8453 20124 1117 TAD PJ1F2 ; now get caller's return address 8454 20125 7001 IAC ; and skip over the argument 8455 20126 6215 .PUSH ; put that on the stack 8456 20127 7200 CLA ; (PUSH doesn't clear the AC!) 8457 20130 1176 TAD [RET1F2] ; the field 1 routine will return to 8458 20131 6215 .PUSH ; ... 8459 20132 7200 CLA ; ... 8460 20133 1020 TAD PUSHAC2 ; restore the original AC contents 8461 20134 6213 CXF 1 ; call with IF = DF = 1 8462 20135 5421 JMP @DESTA ; and go to the code in field 1 8463 8464 ; This routine is identical to TASCIZ, except that the string is stored in 8465 ; field 2, rather than field 0... 8466 20136 3012 TASZF2: DCA MPTR ; save the pointer to the string 8467 20137 1412 TAD @MPTR ; and get the next character 8468 20140 7450 SNA ; is this the end of the string ?? 8469 20141 6225 .POPJ ; yes -- quit now 8470 20142 4100 JMS PJ0F2 8471 20143 7400 OUTCHR 8472 20144 5137 JMP TASZF2+1 ; and then loop until the end 8473 8474 20176 2471 20177 4302 8475 20200 .ORG 0200 8476 8477 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 8478 ; HEX format) stores a checksum of ROM field 2 in location 20200. This is 8479 ; used by the POST and the VE (version) command. 8480 20200 ROMCK2: .BLOCK 1 8481 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 212 Persistent setting support (NVRAM) BTS6120.PLX 8482 .TITLE Persistent setting support (NVRAM) 8483 8484 8485 7700 RDPMLOC = 4032. ; 21*128*1.5 = first free byte in ramdisk 0 DAR 0 8486 ; note: maximum storage is (4096.-4032.-2)/2 words = 31. 8487 0136 RDPMS1 = 0136 ; signature 1 (byte) 8488 0266 RDPMS2 = 0266 ; signature 2 (byte) 8489 8490 20201 7200 RDPSS: CLA 8491 20202 6214 RDF 8492 20203 1377 TAD [CXF 0] 8493 20204 3240 DCA RDPSX 8494 8495 20205 1376 TAD [FIRSTPSS-1] ; set up an auto index register 8496 20206 3013 DCA AX1 ; ... to address the persistent vars 8497 8498 20207 6201 CDF 0 8499 20210 1775 TAD @[RAMBAS] 8500 20211 1374 TAD [RDPMLOC] ; 21*128*1.5 = first free byte in ramdisk field 8501 20212 3014 DCA AX2 ; auto-incr to address NVRAM 8502 8503 20213 6410 LDAR ; set DAR to 0 8504 8505 20214 6403 MM3 ; address the ramdisk memory 8506 ;CDF 0 ; 1st NVRAM 8507 20215 1414 TAD @AX2 ; are the two signature bytes there? 8508 20216 1373 TAD [-RDPMS1] 8509 20217 7640 SZA CLA 8510 20220 5240 JMP RDPSX ; no - exit 8511 20221 1414 TAD @AX2 8512 20222 1372 TAD [-RDPMS2] 8513 20223 7640 SZA CLA 8514 20224 5240 JMP RDPSX ; no - exit 8515 8516 20225 1414 TAD @AX2 ; get the number of words 8517 20226 7041 CIA ; make neg. counter for ISZ 8518 20227 3001 DCA MEA 8519 8520 20230 6403 RDPS0: MM3 8521 ;CDF 0 ; source field 8522 20231 1414 TAD @AX2 ; get the next byte 8523 20232 7002 BSW ; take it as the upper 6 bits 8524 20233 1414 TAD @AX2 ; add in the lower 6 bits 8525 20234 6402 MM2 8526 ;CDF 0 ; destination field 8527 20235 3413 DCA @AX1 ; and store it 8528 20236 2001 ISZ MEA 8529 20237 5230 JMP RDPS0 ; next 8530 8531 20240 0000 RDPSX: 0 8532 20241 6402 MM2 8533 20242 6225 .POPJ 8534 8535 20243 6214 WRPSS: RDF 8536 20244 1377 TAD [CXF 0] 8537 20245 3303 DCA WRPSX 8538 8539 20246 6201 CDF 0 8540 20247 1775 TAD @[RAMBAS] ; starting just after 1st RAM disk page 8541 20250 1374 TAD [RDPMLOC] ; 21*128*1.5 = first free byte in ramdisk field 8542 20251 3014 DCA AX2 ; auto-incr to address NVRAM 8543 8544 20252 1376 TAD [FIRSTPSS-1] ; set up an auto index register 8545 20253 3013 DCA AX1 ; ... to address the persistent vars 8546 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 213 Persistent setting support (NVRAM) BTS6120.PLX 8547 20254 6410 LDAR ; set DAR to 0 8548 8549 20255 6403 MM3 ; address the ramdisk memory 8550 ;CDF 0 8551 8552 20256 1371 TAD [RDPMS1] ; store the signature 8553 20257 3414 DCA @AX2 8554 20260 1370 TAD [RDPMS2] 8555 20261 3414 DCA @AX2 8556 8557 20262 1367 TAD [LASTPSS-FIRSTPSS] ; store the number of words written 8558 20263 3414 DCA @AX2 8559 8560 20264 1366 TAD [FIRSTPSS-LASTPSS] ; -number of words to write 8561 20265 3001 DCA MEA 8562 8563 20266 6402 WRPS0: MM2 8564 ;CDF 0 ; source field 8565 20267 1413 TAD @AX1 ; get a word 8566 20270 6403 MM3 8567 ;CDF 0 ; destination field 8568 20271 6215 .PUSH ; save it for splitting 8569 20272 7002 BSW 8570 20273 0365 AND [77] ; get the upper 6 bits in a byte 8571 20274 3414 DCA @AX2 ; save it 8572 20275 6235 .POP 8573 20276 0365 AND [77] ; get the lower 6 bits in a byte 8574 20277 3414 DCA @AX2 ; save it 8575 8576 20300 2001 ISZ MEA 8577 20301 5266 JMP WRPS0 ; next 8578 8579 20302 6402 MM2 8580 8581 20303 0000 WRPSX: 0 8582 20304 6225 .POPJ 8583 20365 0077 20366 7765 20367 0013 20370 0266 20371 0136 20372 7512 20373 7642 20374 7700 20375 0034 20376 0017 20377 6203 8584 20400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 214 Extension ROM management BTS6120.PLX 8585 .TITLE Extension ROM management 8586 8587 8588 ; check for an extension ROM in ramdisk memory at 100000000. 8589 ; The check looks for a signature of 'SB' 'C6' at the start, and a valid 8590 ; checksum. 8591 8592 20400 7200 EXTROM: CLA 8593 20401 6201 CDF 0 8594 20402 3777 DCA @[EXTFLAG] ; initialize status to "no extension ROM" 8595 8596 ; Reset the console to the serial port just in case, before 8597 ; the extension ROM is loaded 8598 8599 20403 6412 PRISLU 8600 8601 ; If the extension ROM contains code that prevents the SBC from starting up, 8602 ; there needs to be a way to prevent from being called. So a check is made 8603 ; for an ESC character coming in the serial port, and loading is cancelled 8604 ; if it's found. 8605 8606 20404 6031 KSF ; is there a key in the UART buffer? 8607 20405 5212 JMP EXTRO2 ; no, skip check 8608 20406 6036 KRB ; fetch it 8609 20407 1376 TAD [-33] ; compare to ESC 8610 20410 7450 SNA 8611 20411 5277 JMP NOXROM ; was ESC - abort ROM check 8612 8613 ;*** This section of code downloads the first 4KB of the extension ROM 8614 ;*** into field 3 of RAM. For debugging purposes (using an EPROM emulator), 8615 ;*** or if no extension ROM is installed, this may be commented out so 8616 ;*** that what's currently in field 3 is left alone. Since the initial 8617 ;*** EPROM-to-RAM copy copied field 3, the effect is that field 3 of the 8618 ;*** EPROM is used as the extension ROM code. 8619 ;*** !!! important: also disable the memory check of field 3 !!! 8620 20412 7240 EXTRO2: NL7777 ; point the buffer to offset 0 8621 20413 6211 CDF 1 8622 20414 3775 DCA @[BUFPTR] ; ... 8623 20415 1374 TAD [CDF 3] ; of field 3 8624 20416 3773 DCA @[BUFCDF+1] ; ... 8625 20417 7240 NL7777 8626 20420 3772 DCA @[BUFPNL] ; of panel memory 8627 20421 1371 TAD [CDF 1] 8628 20422 3770 DCA @[RAMCDF+1] ; of RAM disk unit 1 (hopefully a ROM) 8629 20423 7240 NL7777 8630 20424 3767 DCA @[RAMPTR] ; beginning of the memory space 8631 20425 6410 LDAR ; and in the first chunk (DAR=0) 8632 20426 1366 TAD [-21.] ; and we'll do it 21 times, for a full 8633 20427 3002 DCA MIA ; field of 2688 words 8634 20430 4117 UNPLP: JMS PJ1F2 8635 20431 0436 UNPACK ; unpack RAM disk data to the buffer 8636 20432 2002 ISZ MIA 8637 20433 5230 JMP UNPLP 8638 ;*** to here 8639 8640 20434 7240 NL7777 8641 20435 3010 DCA SCAN ; check for the two word signature 8642 20436 6231 CDF 3 8643 20437 1410 TAD @SCAN 8644 20440 1365 TAD [-6342] ; 'SB' 8645 20441 7440 SZA 8646 20442 5277 JMP NOXROM ; nope, not there 8647 20443 1410 TAD @SCAN 8648 20444 1364 TAD [-4326] ; 'C6' 8649 20445 7440 SZA PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 215 Extension ROM management BTS6120.PLX 8650 20446 5277 JMP NOXROM ; nope, not there 8651 8652 ; so far so good... checksum it 8653 8654 20447 7240 NL7777 ; starting at beginning of field 8655 20450 3011 DCA ASCAN 8656 20451 1363 TAD [-2688.] ; check the whole downloaded code area 8657 20452 3002 DCA MIA 8658 20453 1411 XRCHECK: TAD @ASCAN ; accumulate checksum 8659 20454 2002 ISZ MIA ; done yet? 8660 20455 5253 JMP XRCHECK ; nope 8661 8662 20456 7450 SNA ; is the checksum 0000? 8663 20457 5262 JMP STARTXROM ; yes, continue the process 8664 8665 20460 7326 NL0002 8666 20461 5275 JMP XROMERR ; no, return error code 0002 8667 8668 ; the extension ROM is present, copied into field 3 and its checksum is valid. 8669 ; Let's call it! 8670 8671 0007 NUMXRARGS=7 ; number of parameters following 8672 8673 20462 STARTXROM: 8674 20462 1362 TAD [NUMXRARGS] 8675 20463 6221 CDF 2 8676 20464 6232 CIF 3 8677 20465 4410 JMS @SCAN 8678 ; parameters passed to Extension ROM entry 8679 20466 0266 VERSION ; BTS6120 ROM version 8680 20467 4306 F0VECTOR ; table of pointers in field 0 8681 20470 4577 F0PATCH-1 ; page that we can use in f0 if needed 8682 20471 2475 F1VECTOR ; table of pointers in field 1 8683 20472 2777 F1PATCH-1 ; page that we can use in f1 if needed 8684 20473 0503 F2VECTOR ; table of pointers in field 1 8685 20474 2377 F2PATCH-1 ; page that we can use in f1 if needed 8686 8687 ; and it returns here with AC=0 for no error, otherwise a code from 0003 up 8688 8689 20475 XROMERR: 8690 20475 6201 CDF 0 8691 20476 3777 DCA @[EXTFLAG] ; save AC as status 8692 20477 6203 NOXROM: CXF 0 8693 20500 6225 .POPJ ; continue initialization process PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 216 Field 2 Vector Table BTS6120.PLX 8694 .TITLE Field 2 Vector Table 8695 8696 8697 20501 6233 RET2F3: CXF 3 ; return to field 3 8698 20502 6225 .POPJ ; the address is already on the stack 8699 8700 8701 ; variable and functions that we may want to access or hook in this field 8702 ; codes: I=instruction pointer, V=variable, H=hook (CIF n, JMP @.+1, V) 8703 ; Add only to the *end* of this list, please! 8704 ; n.b. JMS linkage functions generally cannot be used here 8705 20503 F2VECTOR: 8706 20503 0501 RET2F3 ; I utility - return to field 2 (must be first) 8707 20562 0007 20563 2600 20564 3452 20565 1436 20566 7753 20567 0010 20570 0744 20571 6211 20572 0052 20573 2212 20574 6231 20575 0011 20576 7745 20577 0033 8708 20600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 217 X / XP Commands -- Disassemble memory BTS6120.PLX 8709 .TITLE X / XP Commands -- Disassemble memory 8710 8711 8712 ; CMDX / CMDXP: the disassembler commands. They share an implementation, 8713 ; since the only difference between them is whether main or panel memory is 8714 ; read. 8715 8716 20600 7200 CMDX: CLA 8717 20601 1377 TAD [CPD] ; access main memory 8718 20602 5205 JMP XCOMM 8719 8720 20603 7200 CMDXP: CLA 8721 20604 1376 TAD [SPD] ; access panel memory 8722 20605 3006 XCOMM: DCA DPNL 8723 8724 20606 4100 JMS PJ0F2 ; get the next command character 8725 20607 6101 SPACMP 8726 8727 20610 7450 SNA ; is it an eol? 8728 20611 5270 JMP DFLTX ; yes, goto special handling 8729 8730 20612 4100 JMS PJ0F2 ; no, throw it back in 8731 20613 6131 BACKUP 8732 8733 20614 4100 JMS PJ0F2 8734 20615 6441 RANGE ; and try getting range from input buffer 8735 8736 20616 6201 DA1L: CDF 0 8737 20617 7300 CLA CLL ; for L/LP commands, assume DF=IF 8738 20620 1775 TAD @[ADRFLD] 8739 20621 7012 RTR 8740 20622 7010 RAR 8741 20623 6215 .PUSH ; save the field for later printing 8742 20624 1775 TAD @[ADRFLD] 8743 20625 3005 DCA IFDF ; the two lower digits of IFDF are the same 8744 8745 20626 1774 TAD @[ADDR] ; get the address from RANGE 8746 20627 3003 DCA XPC 8747 8748 20630 1775 TAD @[ADRFLD] ; get the field from RANGE and make a CDF 8749 20631 1373 TAD [CDF 0] 8750 20632 3235 DCA DAF ; self-modify for memory space and field 8751 20633 1006 TAD DPNL 8752 20634 3236 DCA DAP 8753 20635 0000 DAF: 0 8754 20636 0000 DAP: 0 8755 20637 1403 TAD @XPC ; get the code word at the current address 8756 20640 3004 DCA XIR 8757 20641 6201 CDF 0 8758 20642 6276 SPD 8759 8760 20643 6235 .POP ; get back the field number 8761 20644 6205 .PUSHJ DISA2 ; and disassemble the instruction 20645 5331 8762 8763 20646 6201 CDF 0 8764 20647 7200 CLA ; are we at the end of the range? 8765 20650 1775 TAD @[ADRFLD] ; get the field 8766 20651 7041 CIA ; negate the field 8767 20652 1772 TAD @[HGHFLD] ; compare to the high field 8768 20653 7640 SZA CLA 8769 20654 5262 JMP INCR ; no -- continue 8770 20655 1771 TAD @[HIGH] ; yes -- compare the addresses 8771 20656 7041 CIA ; 8772 20657 1774 TAD @[ADDR] ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 218 X / XP Commands -- Disassemble memory BTS6120.PLX 8773 20660 7650 SNA CLA ; are they equal ?? 8774 20661 5310 JMP XCMDDN ; yes -- stop 8775 8776 20662 2774 INCR: ISZ @[ADDR] ; increment address/field 8777 20663 7410 SKP 8778 20664 1370 TAD [10] 8779 20665 1775 TAD @[ADRFLD] 8780 20666 3775 DCA @[ADRFLD] 8781 20667 5216 JMP DA1L 8782 8783 20670 6201 DFLTX: CDF 0 8784 20671 7301 CLL CLA IAC ; AC=0001 L=0 8785 20672 1771 TAD @[HIGH] 8786 20673 3774 DCA @[ADDR] 8787 20674 7430 SZL 8788 20675 1370 TAD [10] 8789 20676 1772 TAD @[HGHFLD] 8790 20677 3775 DCA @[ADRFLD] 8791 20700 7315 CLL CLA IAC R3L ; AC=0010 L=0 8792 20701 1774 TAD @[ADDR] 8793 20702 3771 DCA @[HIGH] 8794 20703 7430 SZL 8795 20704 1370 TAD [10] 8796 20705 1775 TAD @[ADRFLD] 8797 20706 3772 DCA @[HGHFLD] 8798 20707 5216 JMP DA1L 8799 8800 20710 6203 XCMDDN: CXF 0 ; done, 8801 20711 6225 .POPJ ; return to monitor 8802 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 219 Disassemble Current Trace Location BTS6120.PLX 8803 .TITLE Disassemble Current Trace Location 8804 8805 8806 ; XTYPIR: prints a disassembly of the current trace location 8807 8808 20712 1767 XTYPIR: TAD @[UIRPC] ; get the current user environment 8809 20713 3003 DCA XPC ; into our local copies 8810 20714 1766 TAD @[UFLAGS] ; [RLA] UFLAGS is in field zero! 8811 20715 3005 DCA IFDF 8812 20716 1765 TAD @[UIR] 8813 20717 3004 DCA XIR 8814 20720 1377 TAD [CPD] ; a TR always happens in main memory (?) 8815 20721 3006 DCA DPNL 8816 8817 20722 1005 TAD IFDF ; get the IF for printing 8818 20723 7012 RTR 8819 20724 7010 RAR 8820 20725 6205 .PUSHJ DISA2 ; and print the line 20726 5331 8821 8822 20727 6203 CXF 0 ; return to TR 8823 20730 6225 .POPJ 8824 8825 ; DISA2: disassemble a line with all the trimmin's. Displays code address, 8826 ; instruction value, and decoded instruction. Enter with AC=field number. 8827 8828 20731 0365 DISA2: AND [7] ; turn field into ASCII 8829 20732 1364 TAD ["0"] 8830 20733 4100 JMS PJ0F2 ; and print it 8831 20734 7400 OUTCHR 8832 20735 1003 TAD XPC ; print the PC 8833 20736 4100 JMS PJ0F2 8834 20737 6322 TOCT4 8835 20740 1363 TAD [DS4MSG-1] ; say "/ " 8836 20741 6205 .PUSHJ TASZF2 20742 5136 8837 20743 1004 TAD XIR ; print the IR (instruction) 8838 20744 4100 JMS PJ0F2 8839 20745 6322 TOCT4 8840 20746 1362 TAD [DS5MSG-1] ; say "\t" 8841 20747 6205 .PUSHJ TASZF2 20750 5136 8842 20751 6221 CDF 2 8843 20752 5761 JMP @[DISA1] ; and print the disassembled line 8844 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 8845 21000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 220 Disassembler Top Level BTS6120.PLX 8846 .TITLE Disassembler Top Level 8847 8848 21000 7200 DISA1: CLA 8849 21001 3000 DCA MNEMP ; no mnemonics output yet 8850 8851 21002 1004 TAD XIR ; get instruction 8852 21003 7002 BSW 8853 21004 7012 RTR ; extract upper digit 8854 21005 0377 AND [16] 8855 21006 1376 TAD [OPJMP-1] ; and make into table ptr 8856 21007 3010 DCA SCAN 8857 8858 21010 1410 TAD @SCAN ; get pointer to mnemonic list for this group 8859 21011 3011 DCA ASCAN ; SCAN now points to post-mnemonic routine (-1) 8860 8861 21012 1004 TAD XIR ; do 1st mnemonic without sentinel check 8862 21013 0411 AND @ASCAN ; so that opcode 0000 works 8863 21014 5221 JMP MAT0B 8864 8865 21015 1004 AMTCH0: TAD XIR ; get instruction 8866 21016 0411 AND @ASCAN ; AND with mask 8867 21017 7450 SNA ; 0 mask at end of list 8868 21020 5252 JMP AMTCH8 ; no more possible matches 8869 21021 7041 MAT0B: CIA 8870 21022 1411 TAD @ASCAN ; compare masked IR with value 8871 21023 7450 SNA 8872 21024 5232 JMP AMTCH2 ; matched! 8873 8874 ; didn't match, skip over variable-length text to next entry 8875 21025 1411 AMTCH1: TAD @ASCAN ; because all strings are odd length 8876 21026 0375 AND [77] ; just look at the even character 8877 21027 7650 SNA CLA ; for termination symbol (00) 8878 21030 5215 JMP AMTCH0 ; yes, end of text, continue searching 8879 21031 5225 JMP AMTCH1 ; no, skip another word 8880 8881 ; did match, output the mnemonic and go back for more (for case of Operate) 8882 21032 1011 AMTCH2: TAD ASCAN ; save the location for later use in OPRGRP 8883 21033 3000 DCA MNEMP 8884 21034 1411 AMTCH3: TAD @ASCAN ; get the packed 6-bit 8885 21035 6215 .PUSH ; save a couple of copies for later use 8886 21036 6215 .PUSH 8887 21037 7002 BSW ; print the first char 8888 21040 6205 .PUSHJ TSIXB 21041 5262 8889 21042 6235 .POP ; print the second char 8890 21043 6205 .PUSHJ TSIXB 21044 5262 8891 21045 6235 .POP 8892 21046 0375 AND [77] ; was it a space? (n.b. space will have printed) 8893 21047 7640 SZA CLA 8894 21050 5234 JMP AMTCH3 ; no, print next two 8895 21051 5215 JMP AMTCH0 ; look for another mnemonic on this line 8896 8897 ; done with mnemonic part of line 8898 21052 1410 AMTCH8: TAD @SCAN ; call post-mnemonic routine for this group 8899 21053 3001 DCA MEA ; (Bad Things seem to happen when you .PUSHJ 8900 21054 6205 .PUSHJ @MEA ; indirect through an auto-increment location) 21055 5401 8901 21056 7200 CLA 8902 21057 4100 JMS PJ0F2 ; print newline 8903 21060 7104 CRLF 8904 21061 6225 .POPJ 8905 8906 21062 0375 TSIXB: AND [77] ; print a single 6bit character 8907 21063 1374 TAD [" "] PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 221 Disassembler Top Level BTS6120.PLX 8908 21064 4100 JMS PJ0F2 8909 21065 7400 OUTCHR 8910 21066 6225 .POPJ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 222 Disassemble EA For MRIs BTS6120.PLX 8911 .TITLE Disassemble EA For MRIs 8912 8913 8914 ; EAIGRP / EADGRP: post-mnemonic routines for memory reference instructions. 8915 ; prints the effective address (EA) and indirect data values. 8916 8917 21067 1005 EAIGRP: TAD IFDF ; for JMS/JMP, the final destination is in IF 8918 21070 5273 JMP EA2 8919 8920 21071 1005 EADGRP: TAD IFDF ; for AND/TAD/ISZ/DCA, the final value in DF 8921 21072 7114 CLL R3L 8922 21073 0373 EA2: AND [0070] 8923 21074 1372 TAD [CDF 0] ; make into a CDF 8924 21075 3771 DCA @[EA3D] 8925 8926 21076 1005 TAD IFDF ; The initial fetch is always from the IF field 8927 21077 0373 AND [0070] 8928 21100 1372 TAD [CDF 0] ; make into a CDF 8929 21101 3770 DCA @[EA3I] ; and modify the fetch code 8930 8931 21102 1006 TAD DPNL ; get the CPD/SPD and modify the fetch code 8932 21103 3767 DCA @[EA4] 8933 8934 21104 1004 TAD XIR ; get in-page offset from the instruction 8935 21105 0366 AND [177] 8936 21106 7421 MQL ; save it 8937 8938 21107 1004 TAD XIR ; get ZP bit from instruction into Link 8939 21110 7014 R3L 8940 21111 7006 RTL 8941 8942 21112 7200 CLA 8943 21113 1003 TAD XPC ; get current instruction page 8944 21114 0365 AND [7600] 8945 8946 21115 7420 SNL ; test ZP bit in instruction 8947 21116 7200 CLA ; if ZP=0, clear page, otherwise keep PC page 8948 21117 7501 MQA ; combine with offset from instruction 8949 8950 21120 3001 DCA MEA ; now have effective addr 8951 8952 21121 6205 .PUSHJ @[EA3I] ; get value at that address in IF field 21122 5770 8953 21123 3002 DCA MIA 8954 8955 21124 1004 TAD XIR ; get IA bit 8956 21125 7014 R3L 8957 21126 7004 RAL 8958 21127 7620 SNL CLA ; check if IA=0 (not indirect) 8959 21130 5344 JMP EA6 ; yes, do direct directly 8960 8961 21131 1364 TAD [DS2MSG-1] ; Say "@" 8962 21132 6205 .PUSHJ TASZF2 21133 5136 8963 21134 6205 .PUSHJ EA6 ; print " [value]" 21135 5344 8964 21136 1002 TAD MIA ; get double indirect value 8965 21137 3001 DCA MEA 8966 21140 6205 .PUSHJ @[EA3D] ; in correct field (IF if JMP/JMS, else DF) 21141 5771 8967 21142 3002 DCA MIA 8968 21143 5347 JMP EA7 ; print " [value]" and return 8969 8970 21144 1001 EA6: TAD MEA ; print the memory address 8971 21145 4100 JMS PJ0F2 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 223 Disassemble EA For MRIs BTS6120.PLX 8972 21146 6322 TOCT4 8973 21147 1363 EA7: TAD [DS1MSG-1] ; print the indirect (or double-indirect) 8974 21150 6205 .PUSHJ TASZF2 ; value, in format "\t[xxxx]" 21151 5136 8975 21152 1002 TAD MIA 8976 21153 4100 JMS PJ0F2 8977 21154 6322 TOCT4 8978 21155 1362 TAD [DS6MSG-1] 8979 21156 5136 JMP TASZF2 8980 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 8981 21200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 224 Disassemble OPR and IOT instructions BTS6120.PLX 8982 .TITLE Disassemble OPR and IOT instructions 8983 8984 8985 ; OPRGRP: called to finish up a mnemonic Operate instruction. 8986 ; It checks for instructions that have a parameter and also for unknown 8987 ; opcodes. 8988 8989 21200 7300 OPRGRP: CLA CLL 8990 21201 1000 TAD MNEMP ; get last mnemonic output 8991 21202 7450 SNA ; was there one? 8992 21203 5222 JMP NOMNEM ; no - print "?" and return 8993 21204 1377 TAD [-OP6NOCF] ; was it a CDF/CIF/CXF/PR? 8994 21205 7630 SZL CLA 8995 21206 6225 .POPJ ; no - return w/o printing anything 8996 21207 1004 TAD XIR ; get instruction 8997 21210 7012 RTR ; and extract and print field number 8998 21211 7010 RAR 8999 21212 0376 AND [7] 9000 21213 1375 TAD ["0"] 9001 21214 4100 JMS PJ0F2 9002 21215 7400 OUTCHR 9003 21216 6225 .POPJ 9004 9005 ; IOTGRP: called to finish up a mnemonic IOT instruction 9006 ; Since IOTs are hardware defined, we have only a small standard set 9007 ; of them in the tables; so we see if anything useful was printed and, 9008 ; if not, print a '?' 9009 9010 21217 1000 IOTGRP: TAD MNEMP ; any mnemonics output? 9011 21220 7640 SZA CLA 9012 21221 6225 .POPJ ; yes - return w/o printing anything 9013 21222 1374 NOMNEM: TAD [DS3MSG-1] ; Say "?" 9014 21223 5136 JMP TASZF2 9015 9016 ; EA3: fetch word @MEA in correct memory space and field 9017 ; part of EAxGRP, and modifiied by that code 9018 9019 21224 6201 EA3I: CDF 0 ; in field IF (modifed) 9020 21225 7410 SKP 9021 21226 6201 EA3D: CDF 0 ; in field DF (modified) 9022 21227 6266 EA4: CPD ; main or panel memory (modified) 9023 21230 1401 TAD @MEA ; get value at that address 9024 21231 6221 CDF 2 9025 21232 6276 SPD 9026 21233 6225 .POPJ 9027 9028 21374 2272 21375 0060 21376 0007 21377 6310 9029 21400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 225 Disassembler Tables (MRIs) BTS6120.PLX 9030 .TITLE Disassembler Tables (MRIs) 9031 9032 ; Opcode group tables. For each group (upper digit), this 9033 ; table has a mnemonic table pointer and a pointer to a function 9034 ; that prints the parameters (e.g. effective address for AND) 9035 9036 OPJMP: .DATA OP0-1, EADGRP, OP1-1, EADGRP 21400 1417 21401 1071 21402 1423 21403 1071 9037 .DATA OP2-1, EADGRP, OP3-1, EADGRP 21404 1427 21405 1071 21406 1433 21407 1071 9038 .DATA OP4-1, EAIGRP, OP5-1, EAIGRP 21410 1437 21411 1067 21412 1443 21413 1067 9039 .DATA OP6-1, OPRGRP, OP7-1, IOTGRP 21414 1447 21415 1200 21416 1760 21417 1217 9040 9041 ; Mnemonic table. Each entry consists of a mask, a match value, 9042 ; and a text string in sixbit. In order to detect the end of the 9043 ; string, it must be an odd number of characters long so that the 9044 ; last word is xx00. .TEXT could have been used, but 9045 ; it always emits a full word of 0000 and so would have taken more space. 9046 9047 ; the first 6 groups will always match, so no sentinels are necessary 9048 ; The Effective Address will be displayed for these 9049 OP0: .DATA 7000, 0000 21420 7000 21421 0000 9050 21422 .SIXBIT /AND/ 9051 OP1: .DATA 7000, 1000 21424 7000 21425 1000 9052 21426 .SIXBIT /TAD/ 9053 OP2: .DATA 7000, 2000 21430 7000 21431 2000 9054 21432 .SIXBIT /ISZ/ 9055 OP3: .DATA 7000, 3000 21434 7000 21435 3000 9056 21436 .SIXBIT /DCA/ 9057 OP4: .DATA 7000, 4000 21440 7000 21441 4000 9058 21442 .SIXBIT /JMS/ 9059 OP5: .DATA 7000, 5000 21444 7000 21445 5000 9060 21446 .SIXBIT /JMP/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 226 Disassembler Tables (IOTs) BTS6120.PLX 9061 .TITLE Disassembler Tables (IOTs) 9062 9063 21450 OP6: ; mnemonics from here to OP6NOCF will have their 3rd digit 9064 .DATA 7707, 6201 ; printed as the parameter 21450 7707 21451 6201 9065 21452 .SIXBIT /CDF/ 9066 .DATA 7707, 6202 21454 7707 21455 6202 9067 21456 .SIXBIT /CIF/ 9068 .DATA 7707, 6203 21460 7707 21461 6203 9069 21462 .SIXBIT /CXF/ 9070 .DATA 7747, 6206 21464 7747 21465 6206 9071 21466 .SIXBIT /PR / 9072 21470 OP6NOCF: 9073 .DATA 7777, 6214 21470 7777 21471 6214 9074 21472 .SIXBIT /RDF/ 9075 .DATA 7777, 6224 21474 7777 21475 6224 9076 21476 .SIXBIT /RIF/ 9077 .DATA 7777, 6234 21500 7777 21501 6234 9078 21502 .SIXBIT /RIB/ 9079 .DATA 7777, 6244 21504 7777 21505 6244 9080 21506 .SIXBIT /RMF/ 9081 .DATA 7777, 6246 21510 7777 21511 6246 9082 21512 .SIXBIT /WSR/ 9083 .DATA 7777, 6256 21514 7777 21515 6256 9084 21516 .SIXBIT /GCF/ 9085 .DATA 7777, 6266 21520 7777 21521 6266 9086 21522 .SIXBIT /CPD/ 9087 .DATA 7777, 6276 21524 7777 21525 6276 9088 21526 .SIXBIT /SPD/ 9089 .DATA 7777, 6205 21530 7777 21531 6205 9090 21532 .SIXBIT /PPC1 / 9091 .DATA 7777, 6245 21535 7777 21536 6245 9092 21537 .SIXBIT /PPC2 / 9093 .DATA 7777, 6215 21542 7777 21543 6215 9094 21544 .SIXBIT /PAC1 / 9095 .DATA 7777, 6255 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 227 Disassembler Tables (IOTs) BTS6120.PLX 21547 7777 21550 6255 9096 21551 .SIXBIT /PAC2 / 9097 .DATA 7777, 6225 21554 7777 21555 6225 9098 21556 .SIXBIT /RTN1 / 9099 .DATA 7777, 6265 21561 7777 21562 6265 9100 21563 .SIXBIT /RTN2 / 9101 .DATA 7777, 6235 21566 7777 21567 6235 9102 21570 .SIXBIT /POP1 / 9103 .DATA 7777, 6275 21573 7777 21574 6275 9104 21575 .SIXBIT /POP2 / 9105 .DATA 7777, 6207 21600 7777 21601 6207 9106 21602 .SIXBIT /RSP1 / 9107 .DATA 7777, 6227 21605 7777 21606 6227 9108 21607 .SIXBIT /RSP2 / 9109 .DATA 7777, 6217 21612 7777 21613 6217 9110 21614 .SIXBIT /LSP1 / 9111 .DATA 7777, 6237 21617 7777 21620 6237 9112 21621 .SIXBIT /LSP2 / 9113 .DATA 7777, 6207 21624 7777 21625 6207 9114 21626 .SIXBIT /RSP1 / 9115 9116 .DATA 7777, 6000 21631 7777 21632 6000 9117 21633 .SIXBIT "SKON/PRS " 9118 .DATA 7777, 6001 21640 7777 21641 6001 9119 21642 .SIXBIT /ION/ 9120 .DATA 7777, 6002 21644 7777 21645 6002 9121 21646 .SIXBIT /IOF/ 9122 .DATA 7777, 6003 21650 7777 21651 6003 9123 21652 .SIXBIT "SRQ/PGO" 9124 .DATA 7777, 6004 21656 7777 21657 6004 9125 21660 .SIXBIT "GTF/PEX" 9126 .DATA 7777, 6005 21664 7777 21665 6005 9127 21666 .SIXBIT /RTF/ 9128 .DATA 7777, 6006 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 228 Disassembler Tables (IOTs) BTS6120.PLX 21670 7777 21671 6006 9129 21672 .SIXBIT /SGT/ 9130 .DATA 7777, 6007 21674 7777 21675 6007 9131 21676 .SIXBIT /CAF/ 9132 9133 ; console IOTs 9134 .DATA 7777, 6030 21700 7777 21701 6030 9135 21702 .SIXBIT /KCF/ 9136 .DATA 7777, 6031 21704 7777 21705 6031 9137 21706 .SIXBIT /KSF/ 9138 .DATA 7777, 6032 21710 7777 21711 6032 9139 21712 .SIXBIT /KCC/ 9140 .DATA 7777, 6034 21714 7777 21715 6034 9141 21716 .SIXBIT /KRS/ 9142 .DATA 7777, 6035 21720 7777 21721 6035 9143 21722 .SIXBIT /KIE/ 9144 .DATA 7777, 6036 21724 7777 21725 6036 9145 21726 .SIXBIT /KRB/ 9146 .DATA 7777, 6040 21730 7777 21731 6040 9147 21732 .SIXBIT /SPF/ 9148 .DATA 7777, 6041 21734 7777 21735 6041 9149 21736 .SIXBIT /TSF/ 9150 .DATA 7777, 6042 21740 7777 21741 6042 9151 21742 .SIXBIT /TCF/ 9152 .DATA 7777, 6044 21744 7777 21745 6044 9153 21746 .SIXBIT /TPC/ 9154 .DATA 7777, 6045 21750 7777 21751 6045 9155 21752 .SIXBIT /TSK/ 9156 .DATA 7777, 6046 21754 7777 21755 6046 9157 21756 .SIXBIT /TLS/ 9158 21760 0000 0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 229 Disassembler Tables (OPRs) BTS6120.PLX 9159 .TITLE Disassembler Tables (OPRs) 9160 9161 21761 OP7: 9162 ; Group 1 9163 GRP1: .DATA 7600, 7200 21761 7600 21762 7200 9164 21763 .SIXBIT /CLA/ 9165 .DATA 7500, 7100 21765 7500 21766 7100 9166 21767 .SIXBIT /CLL/ 9167 .DATA 7440, 7040 21771 7440 21772 7040 9168 21773 .SIXBIT /CMA/ 9169 .DATA 7420, 7020 21775 7420 21776 7020 9170 21777 .SIXBIT /CML/ 9171 .DATA 7401, 7001 22001 7401 22002 7001 9172 22003 .SIXBIT /IAC/ 9173 .DATA 7416, 7002 22005 7416 22006 7002 9174 22007 .SIXBIT /BSW/ 9175 .DATA 7416, 7004 22011 7416 22012 7004 9176 22013 .SIXBIT /RAL/ 9177 .DATA 7416, 7006 22015 7416 22016 7006 9178 22017 .SIXBIT /RTL/ 9179 .DATA 7416, 7010 22021 7416 22022 7010 9180 22023 .SIXBIT /RAR/ 9181 .DATA 7416, 7012 22025 7416 22026 7012 9182 22027 .SIXBIT /RTR/ 9183 .DATA 7416, 7014 22031 7416 22032 7014 9184 22033 .SIXBIT /R3L/ 9185 .DATA 7777, 7000 22035 7777 22036 7000 9186 22037 .SIXBIT /NOP/ 9187 ; Group 1 composite 9188 .DATA 7777, 7240 22041 7777 22042 7240 9189 22043 .SIXBIT /(STA)/ 9190 .DATA 7777, 7041 22046 7777 22047 7041 9191 22050 .SIXBIT /(CIA)/ 9192 .DATA 7777, 7120 22053 7777 22054 7120 9193 22055 .SIXBIT /(STL)/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 230 Disassembler Tables (OPRs) BTS6120.PLX 9194 .DATA 7777, 7204 22060 7777 22061 7204 9195 22062 .SIXBIT /(GLK)/ 9196 .DATA 7777, 7300 22065 7777 22066 7300 9197 22067 .SIXBIT /(NL0000) / 9198 .DATA 7777, 7301 22074 7777 22075 7301 9199 22076 .SIXBIT /(NL0001) / 9200 .DATA 7777, 7326 22103 7777 22104 7326 9201 22105 .SIXBIT /(NL0002) / 9202 .DATA 7777, 7325 22112 7777 22113 7325 9203 22114 .SIXBIT /(NL0003) / 9204 .DATA 7777, 7307 22121 7777 22122 7307 9205 22123 .SIXBIT /(NL0004) / 9206 .DATA 7777, 7327 22130 7777 22131 7327 9207 22132 .SIXBIT /(NL0006) / 9208 .DATA 7777, 7340 22137 7777 22140 7340 9209 22141 .SIXBIT /(NLM1) / 9210 .DATA 7777, 7344 22145 7777 22146 7344 9211 22147 .SIXBIT /(NLM2) / 9212 .DATA 7777, 7346 22153 7777 22154 7346 9213 22155 .SIXBIT /(NLM3) / 9214 22161 GRP2: 9215 .DATA 7511, 7500 22161 7511 22162 7500 9216 22163 .SIXBIT /SMA/ 9217 .DATA 7451, 7440 22165 7451 22166 7440 9218 22167 .SIXBIT /SZA/ 9219 .DATA 7431, 7420 22171 7431 22172 7420 9220 22173 .SIXBIT /SNL/ 9221 .DATA 7511, 7510 22175 7511 22176 7510 9222 22177 .SIXBIT /SPA/ 9223 .DATA 7451, 7450 22201 7451 22202 7450 9224 22203 .SIXBIT /SNA/ 9225 .DATA 7431, 7430 22205 7431 22206 7430 9226 22207 .SIXBIT /SZL/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 231 Disassembler Tables (OPRs) BTS6120.PLX 9227 .DATA 7601, 7600 22211 7601 22212 7600 9228 22213 .SIXBIT /CLA/ 9229 .DATA 7405, 7404 22215 7405 22216 7404 9230 22217 .SIXBIT /OSR/ 9231 .DATA 7403, 7402 22221 7403 22222 7402 9232 22223 .SIXBIT /HLT/ 9233 .DATA 7777, 7400 22225 7777 22226 7400 9234 22227 .SIXBIT /NOP/ 9235 .DATA 7777, 7410 22231 7777 22232 7410 9236 22233 .SIXBIT /SKP/ 9237 22235 GRP3: 9238 .DATA 7601, 7601 22235 7601 22236 7601 9239 22237 .SIXBIT /CLA/ 9240 .DATA 7501, 7501 22241 7501 22242 7501 9241 22243 .SIXBIT /MQA/ 9242 .DATA 7421, 7421 22245 7421 22246 7421 9243 22247 .SIXBIT /MQL/ 9244 .DATA 7777, 7521 22251 7777 22252 7521 9245 22253 .SIXBIT /SWP/ 9246 .DATA 7777, 7621 22255 7777 22256 7621 9247 22257 .SIXBIT /CAM/ 9248 .DATA 7777, 7701 22261 7777 22262 7701 9249 22263 .SIXBIT /ACL/ 9250 9251 22265 0000 0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 232 Disassembler Messages BTS6120.PLX 9252 .TITLE Disassembler Messages 9253 9254 ; Disassembler messages 9255 9256 22266 DS1MSG: .ASCIZ "\t[" 9257 22271 DS2MSG: .ASCIZ "@" 9258 22273 DS3MSG: .ASCIZ "?" 9259 22275 DS4MSG: .ASCIZ "/ " 9260 22300 DS5MSG: .ASCIZ "\t" 9261 22302 DS6MSG: .ASCIZ "]" 9262 9263 22400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 233 Free Space for Future Expansion! BTS6120.PLX 9264 .TITLE Free Space for Future Expansion! 9265 9266 ; space to put any patch code for this field 9267 22400 F2PATCH: 9268 9269 .END PALX - Program break is 22400 PALX - No errors detected PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 234 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 13-JAN-24 18:41:12 Page 235 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 11111000 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 13-JAN-24 18:41:12 Page 236 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 11110000 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 11111100 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 10000000 00000000 00000000 00000000 00000000 01111111 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 13-JAN-24 18:41:12 Page 237 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 13-JAN-24 18:41:12 Page 238 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 13-JAN-24 18:41:12 Page 239 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 13-JAN-24 18:41:12 Page 240 Symbol Table BTS6120.PLX .ASCIZ -POP- 2929 9256 9257 9258 9259 9260 9261 .BLOCK -POP- 1182 1358 1359 1360 1361 1362 1363 1364 1365 1369 1370 1371 1372 1378 1379 1380 1381 1386 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1404 1405 1406 1407 1408 1411 1412 1413 1414 1415 1418 1419 1422 1423 1424 1425 1428 1429 1430 1477 1478 1481 1484 1495 1499 1500 1501 1506 2085 2321 2322 3171 3216 3469 3470 3585 3657 3726 3845 4181 4182 4969 5507 5789 5793 5794 5795 5796 5800 5801 5802 5803 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5819 5820 5821 5822 5823 5824 5834 6981 7027 7290 7463 7538 8030 8390 8392 8399 8400 8401 8402 8403 8404 8405 8408 8409 8410 8411 8412 8416 8417 8480 .DATA -POP- 1387 8289 8290 8291 8293 8294 8296 8297 8299 8300 8302 8303 8304 8306 8307 8309 8310 8311 9036 9037 9038 9039 9049 9051 9053 9055 9057 9059 9064 9066 9068 9070 9073 9075 9077 9079 9081 9083 9085 9087 9089 9091 9093 9095 9097 9099 9101 9103 9105 9107 9109 9111 9113 9116 9118 9120 9122 9124 9126 9128 9130 9134 9136 9138 9140 9142 9144 9146 9148 9150 9152 9154 9156 9163 9165 9167 9169 9171 9173 9175 9177 9179 9181 9183 9185 9188 9190 9192 9194 9196 9198 9200 9202 9204 9206 9208 9210 9212 9215 9217 9219 9221 9223 9225 9227 9229 9231 9233 9235 9238 9240 9242 9244 9246 9248 .END -POP- 9269 .FIELD -POP- 941 1176 5777 8396 .HM6120 -POP- 56 .NOWARN -POP- 58 .ORG -POP- 1357 1368 1374 1490 5580 5787 5792 5797 5829 8407 8414 8419 8475 .PAGE -POP- 942 1159 1177 1342 1509 1628 1764 1911 2086 2244 2408 2582 2829 3054 3194 3346 3508 3662 3847 3993 4154 4191 4198 4385 4578 4747 4881 5058 5226 5384 5577 5826 6086 6283 6477 6812 6982 7155 7356 7571 7749 7876 8032 8038 8389 8391 8397 8584 8708 8845 8981 9029 9263 .POP -POP- 4699 5421 5446 5467 5471 8572 8760 8889 8891 .POPJ -POP- 1626 1658 1759 1827 1872 1918 1928 1943 2024 2036 2049 2060 2073 2128 2232 2316 2353 2374 2399 2406 2435 2448 2499 2528 2554 2776 2917 2925 2988 2993 3001 3006 3032 3050 3113 3179 3244 3494 3596 3838 3948 3972 3991 4111 4114 4221 4236 4252 4259 4288 4315 4383 4397 4418 4434 4485 4506 4537 4552 4568 4576 4619 4639 4650 4726 4776 4784 4792 4819 4829 4838 4846 4857 4862 4879 4896 4912 4922 4929 5013 5056 5097 5104 5133 5137 5150 5224 5280 5360 5398 5473 5522 5545 5553 5561 5565 5573 5575 5754 5929 5968 5978 6084 6134 6139 6192 6236 6303 6372 6387 6425 6438 6469 6503 6508 6693 6726 6732 6795 6810 6852 6856 6863 6884 6888 6895 6978 7016 7024 7050 7058 7153 7223 7287 7315 7344 7354 7377 7384 7451 7456 7569 7587 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 241 Symbol Table BTS6120.PLX 7673 7747 7827 7833 7847 7852 7855 8018 8027 8469 8533 8582 8693 8698 8801 8823 8904 8910 8995 9003 9012 9026 .PUSH -POP- 4173 4176 4691 5417 5435 5456 8439 8442 8455 8458 8568 8741 8885 8886 .PUSHJ -POP- 1197 1238 1241 1244 1245 1259 1260 1276 1291 1316 1320 1332 1523 1528 1529 1530 1536 1541 1569 1571 1572 1586 1588 1638 1641 1642 1643 1664 1665 1688 1689 1706 1707 1716 1720 1724 1728 1732 1735 1738 1752 1760 1761 1790 1804 1805 1806 1807 1810 1815 1819 1823 1824 1825 1835 1836 1862 1863 1866 1868 1869 1870 1888 1891 1892 1893 1895 1904 1905 1906 1907 1952 1953 1954 1955 1956 1960 1968 2042 2043 2054 2055 2068 2069 2078 2080 2081 2082 2105 2108 2109 2113 2114 2115 2119 2120 2122 2123 2147 2150 2160 2163 2166 2175 2196 2208 2220 2223 2224 2225 2229 2230 2233 2263 2280 2284 2287 2297 2298 2303 2304 2307 2310 2332 2333 2344 2345 2383 2418 2421 2422 2429 2442 2465 2470 2473 2480 2508 2517 2520 2536 2546 2561 2572 2576 2579 2591 2613 2614 2631 2641 2707 2712 2713 2714 2715 2726 2738 2741 2793 2800 2801 2951 2954 2955 2956 2960 2965 2971 2974 2986 2991 2999 3004 3020 3021 3027 3028 3070 3073 3074 3083 3086 3087 3088 3107 3119 3191 3256 3261 3267 3282 3283 3294 3300 3314 3332 3341 3372 3378 3386 3409 3421 3438 3456 3465 3505 3536 3543 3555 3558 3559 3570 3573 3574 3578 3589 3604 3629 3636 3637 3647 3692 3693 3695 3696 3697 3708 3716 3761 3762 3777 3791 3804 3817 3826 3864 3867 3868 3873 3880 3886 3887 3914 3927 3952 3967 3974 3980 4000 4001 4092 4327 4328 4342 4343 4350 4365 4371 4377 4412 4528 4545 4549 4559 4620 4628 4640 4651 4662 4696 4721 4736 4740 4743 4744 4757 4759 4760 4773 4779 4787 4804 4805 4811 4816 4894 4897 4905 4906 4981 5005 5027 5048 5092 5115 5116 5121 5122 5145 5191 5205 5222 5278 5299 5311 5312 5314 5316 5317 5325 5326 5336 5337 5338 5354 5355 5369 5371 5374 5381 5420 5445 5457 5518 5519 5531 5540 5541 5678 5764 5766 5769 5771 5772 5773 5774 5868 5870 5889 6058 6059 6066 6071 6077 6079 6111 6114 6123 6126 6724 6730 6854 6857 6861 6886 6889 6893 6897 7091 7338 7352 7371 7403 7404 7449 7552 7565 7625 7635 7640 7650 7655 7713 7717 7721 7760 7820 8761 8820 8836 8841 8888 8890 8900 8952 8962 8963 8966 8974 .SIXBIT -POP- 8050 8052 8054 8056 8058 8060 8062 8064 8066 8068 8070 8072 8074 8076 8078 8080 8082 8084 8086 8088 8090 8092 8094 8096 8098 8100 8102 8104 8106 8108 8110 8112 8114 8116 8118 8120 8122 8124 8126 8128 8130 8158 8160 8162 8164 8166 8173 8175 8177 8179 8181 8187 8189 9050 9052 9054 9056 9058 9060 9065 9067 9069 9071 9074 9076 9078 9080 9082 9084 9086 9088 9090 9092 9094 9096 9098 9100 9102 9104 9106 9108 9110 9112 9114 9117 9119 9121 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 242 Symbol Table BTS6120.PLX 9123 9125 9127 9129 9131 9135 9137 9139 9141 9143 9145 9147 9149 9151 9153 9155 9157 9164 9166 9168 9170 9172 9174 9176 9178 9180 9182 9184 9186 9189 9191 9193 9195 9197 9199 9201 9203 9205 9207 9209 9211 9213 9216 9218 9220 9222 9224 9226 9228 9230 9232 9234 9236 9239 9241 9243 9245 9247 9249 .STACK -POP- 57 .TEXT -POP- 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8209 8210 8211 8212 8213 8214 8217 8218 8219 8220 8223 8224 8225 8226 8227 8228 8229 8230 8233 8234 8235 8236 8237 8240 8241 8249 8250 8253 8254 8257 8258 8259 8260 8263 8264 8265 8266 8269 8270 8271 8272 8275 8278 8279 8314 8315 8316 8317 8318 8319 8320 8321 8322 8325 8326 8327 8328 8329 8330 8333 8334 8335 8336 8337 8340 8341 8342 8343 8344 8345 8346 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8364 8365 8366 8367 8368 8369 8370 8371 8374 8375 8376 8377 8378 8379 8380 8381 8382 .TITLE -POP- 1 59 141 752 833 882 919 1160 1343 1507 1560 1590 1629 1659 1711 1740 1765 1838 1877 1912 1945 2010 2087 2133 2182 2235 2245 2324 2375 2409 2449 2500 2529 2555 2583 2616 2693 2728 2777 2830 2901 2930 3007 3055 3127 3195 3269 3306 3347 3471 3509 3606 3663 3727 3848 3994 4008 4104 4155 4192 4199 4237 4319 4386 4398 4435 4460 4521 4579 4653 4671 4701 4748 4769 4793 4830 4882 4930 4970 5014 5059 5105 5138 5180 5227 5385 5508 5578 5778 5827 5904 5930 5970 5979 6040 6087 6103 6140 6193 6237 6284 6304 6373 6426 6478 6509 6590 6654 6694 6796 6813 6831 6906 6930 6983 7029 7059 7156 7224 7292 7317 7357 7386 7465 7505 7540 7572 7602 7675 7750 7797 7848 7877 8033 8039 8153 8193 8280 8383 8393 8420 8482 8585 8694 8709 8803 8846 8911 8982 9030 9061 9159 9252 9264 .VECTOR -POP- 5593 ACDISP 06071 4498 4509* ACL 7701 4286 4299 6269 6272 7769 7828 ACNAME 13711 1975 2825 8223* ADDR 00035 1390* 1797 1811 2044 2057 2211 2266 2338 2341 2390 2426 2433 2434 2469 2493 2514 2542 2568 3396 3439 3445 3877 3895 3914 4146 4367 4758 4775 4780 4788 4813 4837 4860 4869 4872 8745 8772 8776 8786 8792 ADRFLD 00036 1391* 2019 2212 2267 2340 2395 2497 2516 2544 2566 2718 2721 3397 3455 4147 4370 4756 4782 4790 4815 4839 4845 4853 4875 4878 5091 5103 8738 8742 8748 8765 8779 8780 8790 8796 ADRPMM 12426 7764 7784* ADRRMD 12410 7767* ALPHA 06627 4897 4906 4917* ALPHA1 06635 4920 4925* AMTCH0 21015 8865* 8878 8895 AMTCH1 21025 8875* 8879 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 243 Symbol Table BTS6120.PLX AMTCH2 21032 8872 8882* AMTCH3 21034 8884* 8894 AMTCH8 21052 8868 8898* AND 0000 1031 1156 1796 1799 1812 1932 1935 2020 2292 2299 2565 2921 3076 3188 3253 3402 3412 3416 3432 3450 3454 3711 3814 3923 4254 4278 4282 4336 4339 4369 4393 4430 4455 4603 4608 4616 4668 4720 4767 4844 5043 5083 5090 5102 5147 5520 5701 5768 5895 5921 6064 6163 6166 6178 6184 6221 6226 6274 6348 6355 6448 6751 6754 6783 6789 6949 6954 7012 7045 7103 7117 7192 7254 7257 7411 7530 7555 7559 7628 7643 7772 7787 7917 7941 7946 7957 7973 7978 8022 8570 8573 8828 8854 8862 8866 8876 8892 8906 8922 8927 8935 8944 8999 ARGPTR 10050 5820* 5917 5926 ASCAN 20011 8409* 8655 8658 8859 8862 8866 8870 8875 8882 8884 AX1 20013 8411* 8496 8527 8545 8565 AX2 20014 8412* 8501 8507 8511 8516 8522 8524 8542 8553 8555 8558 8571 8574 BACKS1 07141 5219 5223* BACKUP 06131 1449 4134 4573* 8731 BADCHK 12732 8012 8020* BADFL 12736 7950 7982 8025* BADFLR 04262 4060 4075 4083* BADFUN 0237 5936* 5954 5955 5956 5957 5958 5959 BANKSZ 0025 6035* 6397 6406 BATTOK 10032 1280 5810* 6278 6302 6327 6368 BFAMSG 14262 1290 8266* BINCH1 03323 3408 3411 3428 3431 3469* BINCH2 03324 3410 3415 3429 3470* BINLO1 03203 3376* 3381 3466 BINLO2 03205 3378* 3383 BINLO3 03214 3386* 3389 BINLO5 03227 3400* 3441 3446 3458 BINLO6 03276 3434 3444* BINLO7 03301 3404 3449* BINLO8 03314 3426 3452 3461* BLIST 01674 2332* 8077 BLIST1 01701 2337* 2348 BLIST2 01715 2343 2347* BMOVE 01400 2105* 8067 BNAMES 13374 2959 8187* BOKMSG 14250 1287 8265* BOOKEY 02421 2910 2929* BOOT 02426 2951* 8117 BOOT1 02452 2953 2971* 4413 BOOTGO 02445 2965* 2973 2976 BOOTS 00412 1526* 1555 BOOTS0 00416 1529* 1532 BOOTS1 00425 1536* 1549 1559 BOOTS2 00435 1539 1544* BPT 6236 795* 2519 5715 5718 BPTADR 00201 1499* 1502 2365 BPTCL2 02030 2443* 2447 BPTCLR 02026 2420 2442* 4001 BPTCO1 02054 2475 2480* BPTCO2 02056 2481* 2486 BPTCO3 02066 2484 2491* BPTCOM 02036 2465* 8079 BPTDAT 00221 1501* 2369 BPTEND 0210 1502* BPTFLD 00211 1500* 2367 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 244 Symbol Table BTS6120.PLX BPTFN1 01741 2386* 2404 BPTFN2 01757 2388 2392 2402* BPTFN3 01760 2397 2403* BPTFND 01737 2383* 2429 2473 BPTIN1 02101 2511* 2527 BPTIN2 02116 2513 2524* BPTIN3 02120 2521 2526* BPTINS 02077 2508* 2641 BPTMSG 13545 5728 8209* BPTRM1 02125 2539* 2553 BPTRM2 02137 2541 2550* BPTRM3 02141 2547 2552* BPTRMV 02123 2536* 5773 BPTTRP 07705 5717 5727* BREMO1 02024 2431 2438* BREMOV 02000 2418* 8081 BRKMSG 13602 5688 8211* BSETUP 01724 2333 2364* 2383 2442 2480 2508 2536 BSW 7002 831 3413 4039 4047 4055 4066 4604 4609 4661 4901 5101 6176 6222 6407 6947 7190 7258 7562 7770 7955 8523 8569 8852 8887 BTIDA0 02500 2974 2997* 8190 BTSTR1 07646 4150 5677 5684* BTSTRP 07636 5645 5663* BTSWCN 00060 1413* 4208 4298 4410 4417 BTVMA0 02464 2971 2984* 8188 BUFCDF 12211 6096 6174 6204 6821 7182 7248 7557 7582 7594* 7600 7872 8624 BUFPNL 10052 5822* 6097 6822 7568 7586 7597 7873 8626 BUFPTR 10011 5794* 6094 6180 6186 6205 6207 6736 6752 6755 6819 7185 7261 7567 7580 7871 8622 BUFSIZ 10053 5823* 6844 6864 6876 6896 7175 7201 7241 7267 7902 7987 8003 8013 BUFTMP 11712 7186 7187 7189 7255 7260 7290* CAF 6007 2755 4433 CAM 7621 3400 CCFMSG 14037 3884 8240* CCPR 6430 783* 2673 4216 CDF 6201 1030 1033 1066 1079 1138 1279 1281 1310 1313 1725 1727 1729 1731 1755 1757 2021 2048 2059 3046 3048 3146 3156 3164 3180 3183 3206 3209 3226 3239 3245 3248 3260 3264 3266 3284 3286 3315 3317 3326 3329 3335 3338 3544 3551 3560 3565 3590 3593 3599 3638 3643 3648 3652 3689 3691 3700 3702 3806 3811 3897 3899 3905 3907 3917 3924 3931 3940 3942 3958 3960 3977 3979 3986 3990 4025 4070 4382 4394 4592 4617 4646 4648 4949 4965 5711 5886 5888 5890 5915 5922 5928 6095 6171 6188 6232 6266 6322 6324 6340 6351 6353 6412 6414 6449 6820 6823 6825 7124 7218 7284 7309 7311 7349 7381 7383 7414 7416 7556 7581 7629 7644 7671 7745 7773 7788 7822 7824 7837 7845 8434 8450 8498 8539 8593 8621 8623 8627 8642 8675 8690 8736 8749 8757 8763 8783 8842 8923 8928 9019 9021 9024 CE1MSG 3772 3875 8245* CEEMSG 4010 8246* CFIELD 01301 2018* 2042 2054 CHBEL 0007 800* 5164 CHBSP 0010 801* 5221 5330 5342 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 245 Symbol Table BTS6120.PLX CHCRT 0015 804* 5190 5342 5345 CHCTC 0003 799* 5525 5530 5535 CHCTO 0017 805* 5535 5539 5548 CHCTR 0022 807* 5306 5310 5321 CHCTU 0025 809* 5321 5324 5330 CHDEL 0177 811* CHESC 0033 810* 5348 5353 5410 5422 CHKERA 12617 7924* 7929 CHKHL1 06042 4453 4458* CHKHLT 06031 2636 2653 4449* 4458 4459 CHKLP 12716 8004 8006* 8014 CHKSUM 00046 1399* 2152 2155 2159 2161 2162 2172 2180 3394 3427 3430 3463 3464 3686 3705 3706 3721 3757 3809 3810 3829 3953 3970 CHLFD 0012 803* 5210 5345 5348 CHNUL 0000 798* CHTAB 0011 802* 1605 1607 1608 5404 5410 CHXOF 0023 808* 5548 5556 CHXON 0021 806* 5556 5564 CIA 7041 1148 2070 2293 2389 2394 2918 3228 3462 3576 3779 3793 3828 3969 4057 4072 4078 4255 4859 4955 5200 5441 6270 6463 7563 7656 7722 8008 8517 8766 8771 8869 CIF 6202 1196 1677 1988 3096 4004 7351 8676 CK1221 10540 1125 6262* 6281 CKBOO1 02404 2914* 2926 CKBOOT 02400 2910* 2986 2999 CKMEM 01442 2147* 8069 CKMEM1 01452 2155* 2167 CKSMSG 13402 2179 8196* CLA 7200 814 815 816 817 818 819 820 821 823 825 827 828 829 830 831 832 951 962 1019 1067 1188 1205 1284 1308 1520 1526 1531 1538 1548 1567 1585 1598 1639 1656 1786 1813 1829 1858 1874 1889 1951 2018 2031 2034 2072 2116 2173 2209 2221 2278 2282 2301 2315 2342 2352 2364 2391 2396 2419 2474 2483 2675 2708 2767 2798 2806 2820 2924 2952 3029 3049 3071 3077 3084 3111 3176 3189 3230 3235 3254 3320 3380 3403 3425 3433 3451 3485 3492 3556 3571 3712 3719 3763 3767 3781 3789 3795 3799 3815 3818 3830 3833 3888 3925 4093 4174 4177 4206 4220 4251 4258 4313 4380 4391 4450 4452 4457 4484 4487 4502 4505 4509 4514 4531 4534 4550 4563 4566 4626 4692 4755 4807 4818 4836 4852 4856 4861 4866 4892 4957 4978 4988 5009 5011 5024 5034 5052 5054 5081 5087 5093 5096 5132 5136 5148 5153 5158 5163 5168 5173 5189 5202 5223 5290 5296 5334 5349 5364 5367 5418 5437 5443 5458 5460 5463 5472 5497 5571 5751 5753 5875 5914 5966 6067 6072 6075 6083 6133 6151 6199 6275 6301 6317 6325 6349 6357 6383 6386 6421 6434 6437 6467 6502 6668 6692 6794 6808 6849 6851 6881 6883 6915 6925 6942 7015 7023 7048 7104 7118 7129 7146 7150 7222 7286 7301 7314 7343 7353 7376 7422 7520 7596 7598 7672 7704 7746 7826 7832 7846 7918 7926 7939 7944 7971 7976 8017 8020 8440 8443 8456 8459 8490 8509 8513 8592 8716 8720 8737 8764 8768 8773 8784 8791 8848 8877 8893 8901 8942 8947 8958 8989 8994 9011 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 246 Symbol Table BTS6120.PLX CLL 7100 816 817 818 819 820 821 823 828 2156 2405 2719 2720 2914 2992 3005 3152 3222 4450 4505 4605 4610 4682 4713 4828 4836 4852 4993 4996 4997 5132 5873 5966 6133 6177 6182 6183 6191 6223 6227 6228 6235 6301 6383 6396 6410 6434 6443 6447 6466 6500 6692 6794 6808 6851 6883 7008 7023 7041 7222 7259 7286 7314 7341 7353 7373 7626 7641 7672 7746 7761 7846 8017 8737 8784 8791 8921 8989 CLRCOM 02300 2738* 8101 CLRCPU 02312 2715 2726 2741 2767* 2965 4000 CLRDRD 0006 6616* 6756 6769 7262 7276 7532 CLRDRE 0012 6620* 6679 CLRDWR 0010 6618* 7196 7210 7496 CMA 7040 818 820 821 823 825 969 3160 3187 3252 3922 4217 4281 4854 4859 5441 5543 6347 6692 6851 6883 7023 CMDBUF 00231 1506* 1570 5269 5315 5357 CMDEDD 0220 6648* CMDIDD 0354 6649* 6727 CMDLEN 00140 1477* 5271 5294 5302 5333 5366 5376 5377 CMDRDS 0040 6650* 6858 CMDSDN 0340 6653* 6926 CMDSUP 0341 6652* 6916 CMDTBL 13200 1540 7865 8049* CMDWRS 0060 6651* 6890 CMDX 20600 2239 8716* CMDXP 20603 2242 8720* CMEM 01507 2208* 8073 CMEM0 01512 2198 2210* CMEM1 01534 2222 2228* 2234 CML 7020 816 817 819 3152 3222 4817 4842 4854 4927 6133 6468 6692 6851 6883 7014 7023 7047 COMERR 00453 1460 1567* 4141 8136 8138 8140 8142 8144 8146 8148 8150 8152 8169 8184 8192 CONCHR 07476 5489 5495 5507* CONF1 07027 5116* 5118 CONF2 07052 5128 5131 5136* CONFRM 07025 3028 3887 4092 5115* CONGE1 03330 3490* 3501 3503 CONGE2 03335 3491 3499* CONGET 03325 3378 3386 3409 3421 3456 3485* CONIN 07552 4127 5519 5571* CONLOD 03200 3372* 8103 CONOU1 07465 5493* 5503 CONOU2 07467 5495* 5504 CONOU3 07473 5494 5502* CONOUT 07463 4126 5468 5489* CONT 02216 2615 2636* 2723 2727 2968 4309 CONT1 02227 2606 2644 2669* 5679 CONT2 02225 2653* 5899 CONTCM 02214 2631* 8083 COUNT 00067 1424* 2118 2126 2290 2306 2314 2347 2372 2403 2446 2485 2526 2552 2812 2815 2819 3080 3091 3106 3108 3109 3118 3122 3153 3162 3223 3237 3377 3382 3683 3694 3709 3710 3717 3754 3765 3794 3812 3813 3985 3988 CP1MSG 14056 3893 8241* CP2MSG 4003 3933 8242* CPANEL 01310 2031* 2043 2055 CPBOOT 07600 5593 5594* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 247 Symbol Table BTS6120.PLX CPD 6266 1097 1105 2035 2919 4231 4351 4378 5705 5925 7599 7631 7633 7646 7648 7790 7792 8717 8814 9022 CPSAVE 07602 1234 5611* CPYDST 0041 1432* 3870 3885 3939 3957 CPYSRC 0040 1431* 3866 3904 CRLF 07104 1445 4131 5189* 8903 CRLF1 07127 5199 5203 5210* CS1FX 0100 6626* 6628 6629 6630 6631 6632 6633 6634 6635 6636 CS3FX 0200 6627* CTRLO 00051 1404* 5273 5283 5459 5528 5542 5544 CXF 6203 1130 1186 2238 2241 4110 4113 4179 5594 5629 5719 5722 5898 5902 5977 7851 7854 8445 8461 8492 8536 8692 8697 8800 8822 DA1L 20616 8736* 8781 8798 DAC 01200 1916* 8174 DAF 20635 8750 8753* DANDV 01342 1458 2066* DAP 20636 8752 8754* DBCHKS 04153 3952 3967 3982* DCA 3000 964 966 978 980 982 984 986 988 1020 1024 1032 1068 1078 1096 1098 1139 1141 1143 1146 1235 1311 1533 1545 1556 1558 1568 1624 1650 1654 1657 1676 1700 1709 1754 1787 1797 1801 1859 1917 1922 1927 1937 1966 2022 2045 2053 2057 2066 2110 2118 2151 2152 2159 2162 2210 2211 2212 2214 2216 2217 2265 2266 2267 2269 2271 2273 2274 2286 2290 2294 2306 2334 2338 2340 2366 2368 2370 2372 2373 2426 2433 2434 2443 2444 2445 2469 2492 2494 2496 2498 2514 2516 2518 2542 2544 2566 2568 2570 2571 2573 2605 2642 2670 2717 2722 2768 2769 2770 2771 2772 2773 2775 2795 2796 2812 2816 2911 2913 2967 3025 3080 3093 3095 3106 3124 3147 3148 3153 3155 3158 3161 3207 3208 3223 3225 3285 3288 3291 3293 3297 3299 3316 3323 3328 3331 3337 3340 3373 3377 3391 3394 3396 3397 3408 3410 3418 3422 3430 3445 3455 3457 3464 3487 3530 3532 3538 3540 3546 3548 3549 3550 3552 3562 3564 3567 3577 3600 3623 3625 3631 3633 3640 3642 3649 3651 3682 3683 3685 3686 3703 3706 3751 3753 3754 3756 3757 3786 3807 3810 3866 3870 3877 3895 3898 3906 3941 3953 3959 3983 3985 3998 3999 4036 4041 4044 4049 4052 4063 4088 4099 4101 4168 4170 4207 4208 4209 4218 4233 4279 4285 4298 4326 4341 4353 4367 4370 4395 4417 4425 4426 4427 4428 4431 4432 4575 4587 4589 4598 4601 4636 4645 4659 4677 4678 4707 4709 4715 4718 4731 4775 4781 4783 4789 4791 4813 4815 4825 4827 4845 4870 4872 4876 4878 4893 4902 4911 4948 4964 4979 4980 4994 5001 5025 5026 5039 5046 5091 5103 5119 5192 5204 5207 5220 5268 5270 5271 5272 5273 5281 5282 5283 5284 5301 5309 5356 5358 5377 5489 5490 5528 5529 5538 5544 5552 5559 5560 5611 5613 5615 5617 5619 5632 5699 5703 5707 5709 5871 5879 5881 5891 5893 5897 5917 5923 6060 6065 6094 6096 6097 6098 6099 6153 6164 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 248 Symbol Table BTS6120.PLX 6167 6169 6180 6186 6201 6206 6208 6217 6219 6224 6230 6271 6278 6327 6342 6344 6352 6368 6370 6394 6408 6415 6450 6461 6464 6498 6506 6669 6736 6738 6752 6755 6764 6784 6791 6819 6821 6822 6826 6827 6844 6876 6950 7004 7005 7076 7080 7082 7083 7097 7099 7113 7125 7141 7175 7177 7186 7241 7243 7255 7261 7303 7305 7310 7337 7339 7347 7350 7372 7380 7405 7413 7417 7425 7482 7531 7553 7557 7564 7567 7568 7580 7582 7584 7586 7630 7634 7637 7645 7649 7652 7657 7665 7707 7711 7715 7719 7723 7738 7759 7774 7776 7778 7789 7793 7795 7839 7844 7902 7912 7914 7923 7936 7938 7958 7961 7965 7969 7991 7996 8000 8003 8433 8436 8449 8452 8466 8493 8496 8501 8518 8527 8537 8542 8545 8553 8555 8558 8561 8571 8574 8594 8622 8624 8626 8628 8630 8633 8641 8655 8657 8691 8722 8743 8746 8750 8752 8756 8780 8786 8790 8793 8797 8809 8811 8813 8815 8849 8856 8859 8883 8899 8924 8929 8932 8950 8953 8965 8967 DDBUF 03600 3589 3682* DDBUF2 03605 3689* 3720 DDBUF3 03623 3700* 3713 DDCNT 03652 3682 3718 3726* 3751 3766 DDDUMP 03405 3536* 8105 DDUMP1 03463 3557 3572 3581* 3595 DECNW 06662 1642 1664 1688 1706 4978* DECNW1 06667 4984* 5006 DECNW2 06713 4986 4989 5009* DERCKS 03766 3831 3841* DESTA 20021 8417* 8436 8446 8452 8462 DFLTX 20670 8728 8783* DFRMAT 03072 3282* 8113 DIGITS 00070 1425* 4589 4593 4598 4678 4686 4693 4709 4724 4980 5004 5010 5026 5047 5053 5094 DIOERR 03504 3173 3218 3587 3599* 3659 3912 3947 3965 DISA1 21000 8843 8848* DISA2 20731 8761 8820 8828* DISASM 01546 2238* 8127 DISASMP 01550 2241* 8129 DISKID 11042 1307 6724* DISKIO 12060 7425 7449 7460 7463* DISKRD 11214 3298 3537 3910 3963 6829 6841* 7423 7866 DISKRW 12017 5942 7403* DISKWR 11244 3292 3630 3945 6873* 7423 7424 7867 DKPART 10020 3285 3546 3642 3906 3941 3959 5800* 6826 6951 6958 7303 7308 7312 7337 7348 7417 7869 DKRBN 10021 1474 3918 3923 5801* 6827 6943 6946 7405 7452 7870 7904 7916 7954 DKRW0 12024 7410* DKRW1 12041 7445* 7455 DKRW2 12056 7447 7459* DKSIZE 10022 1312 3047 5802* 6669 6784 6790 6791 6809 6848 6880 7874 DKUNIT 10023 5803* 7339 7340 7345 7372 7375 7378 DLLOAD 03520 3629* 8109 DLOAD 03526 3626 3636* DLOAD1 03540 3646* 3660 4102 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 249 Symbol Table BTS6120.PLX DMEM 01067 1858* 8059 DMEM1 01075 1866* 1876 DMQ 01206 1926* 8178 DNAMES 13360 1908 8173* DPC 01203 1921* 8176 DPMEM 01065 1855* 8061 DPNL 20006 8405* 8722 8751 8815 8931 DPS 01211 1931* 8180 DRD1 11225 6850 6854* DREG 01132 1904* 8065 DRVERR 11442 7010 7043 7055* DS1MSG 22266 8973 9256* DS2MSG 22271 8961 9257* DS3MSG 22273 9013 9258* DS4MSG 22275 8835 9259* DS5MSG 22300 8840 9260* DS6MSG 22302 8978 9261* DSKBUF 17400 1311 1319 3154 3224 3684 3752 3982 6735 6780 6785 7579 7960 7995 8390* DSR 01221 1941* 8182 DSTCDF 12265 7645 7663* DSTDAR 0025 7702* 7711 7735 DSTSPD 12266 7649 7664* DWR1 11255 6882 6886* EA2 21073 8918 8922* EA3D 21226 8924 8966 9021* EA3I 21224 8929 8952 9019* EA4 21227 8932 9022* EA6 21144 8959 8963 8970* EA7 21147 8968 8973* EADGRP 21071 8920* 9036 9037 EAIGRP 21067 8917* 9038 EMEM 01002 1786* 8055 EMEM0 01004 1790* 1831 EMEM1 01017 1804* 1816 EMEM2 01021 1805* 1814 EMEM3 01044 1809 1823* ENAMES 13344 1894 8158* EOLNXT 06112 1451 4136 4545* EOLTST 06114 1450 4135 4549* EONE 01042 1792 1819* EPMEM 01000 1783* 8057 ERABLK 12626 7927 7935* EREG 01114 1888* 8063 ERRAST 13670 2477 8219* ERRBTF 13701 2488 8220* ERRCKS 13513 3842 8204* ERRDIO 13502 3602 8203* ERRDSK 14010 3263 3976 8237* 8246 ERRILV 13430 1683 2809 3036 3102 8198* ERRNBP 13653 2355 8217* ERRNBT 13526 2980 8205* ERRNDK 13537 3052 8206* ERRNST 13662 2439 8218* ERROR 00465 1461 1584* 1587 ERRRAN 13453 4821 8200* ERRSRF 13442 2318 8199* ERRWRP 13464 2132 8201* EXMEM 05751 1923 1938 2762 4327 4342 4365 4377* 5774 EXTFLAG 00033 1252 1258 1386* 6323 8594 8691 EXTRO2 20412 8607 8620* EXTROM 20400 1197 8592* F0PATCH 04600 4196* 8681 F0VECTOR 04306 4120* 8680 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 250 Symbol Table BTS6120.PLX F1ADDR 04416 4170 4181* F1PATCH 13000 8036* 8683 F1VECTOR 12475 7862* 8682 F1X0 10000 5789* F2PATCH 22400 8685 9267* F2VECTOR 20503 8684 8705* FCFMSG 13743 3023 8233* FCMDCS 0120 4015* 7911 FCMDERA1 0040 4016* 7935 FCMDERA2 0320 4017* 7937 FCMDPROG 0100 4018* 7964 FCMDRA 7777 4013* 4035 4051 4087 7913 7990 FCMDRI 0220 4014* 4043 4062 FIRSTPSS 0020 1377* 8495 8544 8557 8560 FLDTS1 10127 1142* 1145 FLDTS2 10134 1147* 1153 FLDTST 10122 1106 1114 1137* 1157 FLLOAD 04213 4024* 8123 FLMEM 01503 2196* 8075 FLMSG1 14343 4084 8278* FLMSG2 14352 4091 8279* FLNXT 12700 7980 7984* FM1MSG 13763 3145 8234* FM2MSG 13772 3205 8235* 8245 FM3MSG 14003 3304 8236* 8242 FMTARG 02514 3020* 3283 3314 FMTCNT 00073 1430* 3157 3159 3177 3188 3227 3233 3242 3253 3291 3297 3328 3337 FMTP1 02666 3144* 3294 3332 FMTP11 02673 3151* 3190 3192 FMTP12 02701 3157* 3163 FMTP2 03000 3204* 3300 3341 FMTP21 03006 3212* 3255 3257 FMTP22 03023 3227* 3238 FMTP23 03040 3242* 3268 FMTP29 03057 3231 3236 3260* FMTRDP 03012 3216* 3299 3340 FMTWRP 02715 3171* 3293 3331 FNSTAT 00057 1412* 4207 4256 4280 4285 FPDTCT 00056 1411* 4218 4219 4250 4451 4483 7823 FPINIT 05600 1241 4206* FPPGMD 00062 1415* 4519 7839 FPPGMM 00061 1414* 2773 4209 4432 4486 7844 FRDONE 03115 3303* 3344 FTCONT 0310 3483* 3486 FUNTBL 10261 5878 5938* 5962 7864 GCF 6256 5612 GET 00475 1452 1598* 4137 GET1 00515 1602 1618* GET2 00521 1615 1624* GETARG 10241 5868 5870 5914* 6059 7338 7371 7404 7552 7565 7625 7635 7640 7650 7655 7713 7717 7721 7760 7820 GETBAT 10600 5941 6301* GETDKS 11131 5943 6808* GETPMP 12000 5945 7371* GETPP 04000 3864* 3873 3880 GETRDS 11000 5940 6498* GETVER 10302 5938 5966* GOOD 01367 2066 2067 2071 2079 2085* GRP1 21761 9163* GRP2 22161 9214* GRP3 22235 9237* HALTED 07711 2654 5649 5671 5750* HELLO 00701 1245 1717* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 251 Symbol Table BTS6120.PLX HELP 00736 1752* 8051 HELP1 00742 1755* 1762 HGHFLD 00042 1395* 2216 2271 4149 4783 4827 4855 8767 8789 8797 HIGH 00040 1393* 1431 1798 1801 2214 2269 4049 4073 4079 4148 4781 4825 4858 8770 8785 8793 HLPB 16366 8304 8361* HLPBL 15421 8297 8336* HLPBM 15116 8294 8326* HLPBP 15346 8297 8334* HLPBPC 15330 8296 8333* HLPBR 15372 8297 8335* HLPC 15547 8300 8342* HLPCK 15153 8294 8327* HLPCM 15301 8294 8330* HLPCTC 17075 8310 8378* HLPCTH 17130 8310 8379* HLPCTL 16730 8309 8374* HLPCTO 17042 8310 8377* HLPCTQ 17004 8310 8376* HLPCTR 17246 8310 8381* HLPCTS 16745 8310 8375* HLPCTU 17301 8310 8382* HLPD 14741 8291 8320* HLPDD 16060 8303 8354* HLPDF 16145 8303 8356* HLPDL 16117 8303 8355* HLPDOL 16703 8307 8371* HLPDP 15005 8291 8321* HLPDR 15052 8291 8322* HLPDSK 15715 8302 8349* HLPE 14511 8290 8315* HLPEDC 14465 8289 8314* HLPEP 14553 8290 8316* HLPER 14616 8290 8317* HLPEX 15642 8300 8345* HLPFL 16343 8304 8360* HLPFM 15247 8294 8329* HLPLP 15727 8303 8350* HLPLST 14365 1753 8287* HLPMEM 15103 8293 8325* HLPMR 15676 8300 8346* HLPMSC 16416 8306 8364* HLPNUL 14464 8293 8296 8299 8302 8306 8309 8311* HLPP 15443 8297 8337* HLPPC 16235 8304 8358* HLPPCC 15471 8299 8340* HLPPE 16274 8304 8359* HLPPM 16172 8304 8357* HLPRD 15754 8303 8351* HLPRF 16035 8303 8353* HLPRL 16011 8303 8352* HLPRP 16641 8307 8370* HLPRUB 17201 8310 8380* HLPSC 16520 8307 8367* HLPSEM 16600 8307 8369* HLPSI 15572 8300 8343* HLPST 15512 8300 8341* HLPTP 16465 8307 8366* HLPTR 15615 8300 8344* HLPTW 16436 8307 8365* HLPVE 16553 8307 8368* HLPWS 15210 8294 8328* HLPX 14643 8290 8318* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 252 Symbol Table BTS6120.PLX HLPXP 14702 8290 8319* HLT 7402 2603 HLTMSG 13625 5756 8213* HPOS 00053 1406* 5146 5192 5217 5220 5436 5442 IAC 7001 815 827 828 829 830 831 832 951 1019 1067 2158 3234 3499 4172 4270 4854 6133 6277 6446 6676 7102 8438 8454 8784 8791 IDAMSG 14112 3003 8254* IDBOOT 11200 2998 6818* IDDEV1 11065 6748* 6759 IDDEV2 11103 6765* 6772 IDEINI 11013 1303 6668* IDEINP 0222 6613* 6670 6739 7220 7244 7502 7521 IDEMS1 14275 1301 8269* IDEMS2 14302 1318 8270* IDEMS3 14307 1331 8271* IDEMS4 14320 1326 8272* IDEOUT 0200 6614* 7178 7483 IDERDR 12101 6686 7006 7039 7055 7519* 7523 7524 7535 IDETMP 12122 7482 7492 7531 7534 7538* IDEWRR 12061 6683 6728 6859 6891 6917 6927 6944 6956 6961 6971 6976 7481* 7485 7486 7504 IFDF 20005 8404* 8743 8811 8817 8917 8920 8926 ILLPR0 07707 5731* 5903 INCH10 07356 5297 5381* INCHBS 07300 5333* 5365 INCHR1 07517 5527 5535* INCHR2 07534 5537 5548* INCHR3 07542 5550 5556* INCHR4 07550 5558 5564* INCHRS 07477 2297 4129 5116 5278 5457 5518* INCHW1 07210 1530 3762 5278* 5303 5318 5335 5368 5378 5382 INCHW2 07227 5294* 5350 INCHW3 07242 5288 5306* INCHW4 07264 5308 5321* INCHW5 07275 5323 5330* INCHW6 07312 5332 5342* INCHW7 07326 5344 5347 5355* INCHW8 07335 5291 5363* INCHW9 07350 5339 5374* INCHWL 07200 1528 3761 5268* 5327 INCR 20662 8769 8776* INIPM1 11721 7307* 7313 INIPMP 11713 2761 4003 7301* INLMES 06237 1446 4625* 4627 4629 4630 IOTGRP 21217 9010* 9039 IRMA 00055 1408* 3487 3502 5490 5502 IRNAME 13722 8226* ISZ 2000 1025 1070 1100 1144 1152 2126 2346 2347 2402 2403 2446 2481 2485 2524 2525 2526 2550 2551 2552 2815 3108 3162 3177 3181 3182 3237 3242 3246 3247 3382 3439 3502 3591 3592 3594 3709 3783 3812 3918 3988 4354 4363 4410 4458 4593 4629 4686 4724 4837 4959 5004 5047 5195 5302 5436 5502 5918 6080 6081 6189 6233 6400 6758 6771 7017 7019 7084 7144 7198 7201 7212 7264 7267 7278 7312 7445 7452 7454 7486 7524 7666 7739 7928 7984 7987 8013 8528 8576 8636 8659 8776 JMP 5000 954 971 1026 1029 1034 1071 1073 1076 1080 1101 1108 1116 1131 1145 1151 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 253 Symbol Table BTS6120.PLX 1153 1157 1208 1212 1215 1224 1227 1254 1283 1285 1288 1305 1309 1315 1321 1327 1338 1532 1539 1549 1555 1559 1573 1589 1602 1615 1640 1668 1671 1674 1678 1692 1695 1698 1701 1710 1739 1762 1792 1809 1814 1816 1830 1831 1837 1875 1876 1890 1896 1909 1923 1938 1957 1961 1970 1989 2107 2125 2127 2149 2165 2167 2174 2181 2198 2222 2234 2239 2242 2279 2283 2302 2309 2311 2343 2348 2388 2392 2397 2404 2420 2425 2431 2447 2468 2475 2484 2486 2513 2521 2527 2541 2547 2553 2580 2606 2615 2637 2644 2654 2686 2709 2723 2727 2754 2762 2799 2807 2821 2827 2926 2953 2962 2968 2973 2976 3030 3072 3078 3085 3097 3112 3126 3163 3173 3190 3192 3218 3231 3236 3238 3255 3257 3268 3305 3321 3344 3381 3383 3389 3404 3426 3434 3441 3446 3452 3458 3466 3491 3501 3503 3506 3533 3557 3572 3587 3595 3626 3659 3660 3713 3720 3722 3764 3768 3782 3784 3790 3796 3800 3816 3819 3820 3831 3834 3871 3878 3889 3912 3920 3926 3928 3934 3947 3965 3989 4005 4060 4075 4081 4085 4094 4102 4180 4272 4296 4301 4304 4306 4309 4311 4314 4329 4344 4356 4372 4411 4413 4453 4459 4488 4492 4495 4498 4511 4516 4520 4535 4551 4567 4594 4612 4621 4630 4641 4652 4670 4685 4687 4695 4700 4725 4733 4737 4741 4745 4761 4768 4808 4899 4908 4920 4954 4958 4960 4966 4986 4989 5006 5012 5032 5035 5049 5055 5084 5118 5128 5131 5149 5155 5160 5165 5170 5175 5179 5199 5203 5211 5219 5275 5288 5291 5297 5303 5308 5318 5323 5327 5332 5335 5339 5344 5347 5350 5365 5368 5378 5382 5401 5406 5407 5412 5414 5423 5440 5444 5461 5464 5468 5494 5499 5503 5504 5527 5532 5537 5550 5558 5595 5630 5643 5645 5649 5671 5677 5679 5717 5721 5775 5876 5899 5903 6068 6073 6076 6078 6082 6113 6116 6117 6125 6128 6129 6190 6234 6281 6326 6329 6350 6358 6362 6399 6401 6475 6678 6690 6759 6772 6829 6850 6865 6882 6905 6919 6929 7010 7018 7020 7043 7049 7085 7105 7128 7151 7200 7202 7213 7266 7268 7279 7313 7447 7455 7460 7504 7535 7600 7667 7740 7764 7780 7796 7830 7919 7927 7929 7930 7943 7948 7950 7975 7980 7982 7988 8004 8012 8014 8446 8462 8472 8510 8514 8529 8577 8607 8611 8637 8646 8650 8660 8663 8666 8718 8728 8769 8774 8781 8798 8843 8863 8868 8872 8878 8879 8894 8895 8918 8959 8968 8979 8992 9014 JMS 4000 1106 1114 1125 1256 1270 1272 1274 1277 1286 1289 1300 1302 1306 1317 1325 1330 1682 1717 1721 1733 1736 1974 1979 1984 1993 1998 2003 2008 2076 2131 2178 2317 2354 2438 2476 2487 2636 2653 2760 2808 2822 2824 2979 2984 2989 2997 3002 3022 3035 3051 3101 3116 3120 3144 3167 3170 3204 3212 3215 3262 3303 3318 3581 3584 3601 3653 3656 3841 3874 3883 3892 3902 3909 3932 3937 3944 3955 3962 3975 4002 4083 4090 4820 5657 5687 5723 5727 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 254 Symbol Table BTS6120.PLX 5731 5755 6160 6174 6204 6214 6683 6686 6728 6859 6891 6917 6927 6944 6956 6961 6971 6976 7006 7039 7055 7094 7182 7248 7706 7710 8470 8634 8677 8724 8730 8733 8830 8833 8838 8902 8908 8971 8976 9001 KCC 6032 763* 1222 KEY 01672 2265 2291 2294 2300 2321* KRB 6036 765* 3493 5574 8608 KRS 6034 764* KSF 6031 762* 1225 3490 5572 8606 L 00013 1372* 1544 1558 1568 1599 1653 4574 4575 5270 5301 5309 5356 5358 5370 LAS 7604 2007 4325 4335 4352 LASTPSS 0033 1382* 8557 8560 LBATMP 11344 6950 6955 6981* LDAR 6410 6038* 6264 6338 6424 7093 7112 7115 7729 7736 7907 8503 8547 8631 LDBU20 03665 3762* 3764 LDBUF 03653 3647 3751* LDBUF2 03662 3760* 3820 LDBUF3 03710 3782 3787* LDBUF4 03727 3804* 3816 LDBUF5 03752 3768 3826* LDPAGE 03770 3756 3780 3783 3786 3837 3845* LENGTH 00031 1380* 1700 3999 5197 LIGHT1 12465 7830 7844* LIGHTS 12442 5948 7820* LOW 00041 1394* 1432 1795 2492 2494 2496 2498 4041 4058 4077 4789 4812 4824 4867 4870 LOWFLD 00043 1396* 4791 4814 4826 4873 4876 LSP1 6217 1190 1522 2677 5628 LSP2 6237 2679 MASK 01673 2273 2286 2292 2299 2322* MAT0B 21021 8863 8869* MATCH 06642 1541 1895 1909 2960 4948* MATCH1 06644 4952* 4960 MATCH2 06655 4954 4958 4963* MATCH3 06661 4964 4966 4969* MAXBPT 0010 1498* 1499 1500 1501 1502 2371 MAXCMD 0147 1505* 1506 5295 MAXFUN 0020 5874 5962* MCALL 10201 5721 5868* MCALL1 10225 5890* MCALL2 10237 5876 5902* 5936 MEA 20001 8400* 8518 8528 8561 8576 8899 8900 8950 8965 8970 9023 MEMMOV 12220 5946 7625* MEMMSG 13413 2077 8197* MEMMVX 12276 5947 7704* MEMTS1 10107 1106* 1108 MEMTS2 10114 1114* 1116 MIA 20002 8401* 8633 8636 8657 8659 8953 8964 8967 8975 MM0 6400 878* MM1 6401 879* 1021 MM2 6402 880* 1023 4069 6170 6231 6280 6371 7123 7306 7743 7794 7966 8006 8016 8025 8525 8532 8563 8579 MM3 6403 881* 4024 6161 6215 6265 6339 7095 7777 7909 7963 7968 8009 8505 8520 8549 8566 MNEMP 20000 8399* 8849 8883 8990 9010 MOVE1 01411 2113* 2127 MOVE2 01440 2125 2131* MPTR 20012 8410* 8466 8467 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 255 Symbol Table BTS6120.PLX MQA 7501 1936 3417 4340 4611 4871 4877 5614 8948 MQDISP 06074 4495 4514* MQL 7421 1933 2681 3414 4283 4297 4337 4606 4868 4874 6268 7731 7768 7821 8936 MQNAME 13717 1985 8225* MUUO 10047 5819* 5871 5872 5877 5879 5880 5881 5889 5893 5896 6063 6074 7410 7421 7553 7554 7558 MVXARG 12400 7706 7710 7758* 7780 7796 NAME 00045 1398* 1537 4893 4902 4910 4911 4956 NAMENW 06600 1536 1892 1904 2955 4892* NL0000 7200 814* NL0001 7201 815* 6365 6369 6975 NL0002 7326 816* 6137 8665 NL0003 7325 827* 3504 NL0004 7307 828* NL0006 7327 829* NL0010 7215 832* 7307 NL0100 7203 831* NL2000 7332 817* NL3777 7350 818* 1649 5894 NL4000 7330 819* 7561 NL5777 7352 820* NL6000 7333 830* NL7775 7346 821* 822 NL7776 7344 823* 824 NL7777 7240 825* 826 2912 7585 8620 8625 8629 8640 8654 NLM1 7240 826* 3566 6361 6367 NLM2 7344 824* 4599 6276 6328 7583 NLM3 7346 822* 4588 4597 4732 NOBOOT 02462 2962 2979* NODISK 02537 3043* 3282 3536 3629 4143 NOERA 12646 7919 7930 7948 7954* NOMNEM 21222 8992 9013* NOP 7000 1140 1339 1340 1515 1516 1517 2814 3043 3044 3045 3440 4355 4364 4396 5196 5684 5685 5686 5704 5919 5924 6474 6767 6768 6841 6842 6843 6873 6874 6875 7453 7528 7595 7660 7661 7663 7664 7725 7726 7727 7732 7733 7734 7985 NORDM 00311 1283 1288 1291* NOUNIT 02535 3035* 3321 NOXRMES 00263 1254 1261* NOXROM 20477 8611 8646 8650 8692* NUMXRARGS 0007 8671* 8674 NX1 12741 7923 7924 7928 7958 7965 7969 7984 7998 8030* NXTADR 06473 1456 4836* OCTN1 06725 5030* 5049 OCTN2 06750 5032 5035 5052* OCTNF 07004 4773 5087* OCTNF1 07010 5084 5091* OCTNI 07000 2422 2465 2713 5081* OCTNW 06720 1453 4138 5024* OKFLR 04265 4081 4087* OP0 21420 9036 9049* OP1 21424 9036 9051* OP2 21430 9037 9053* OP3 21434 9037 9055* OP4 21440 9038 9057* OP5 21444 9038 9059* OP6 21450 9039 9063* OP6NOCF 21470 8993 9072* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 256 Symbol Table BTS6120.PLX OP7 21761 9039 9161* OPJMP 21400 8855 9036* OPRGRP 21200 8989* 9039 OUTCH1 07411 5406 5410* OUTCH2 07416 5412 5417* OUTCH3 07426 5401 5426* OUTCHR 07400 1435 4128 5397* 8471 8831 8909 9002 OUTST1 06204 4592* 4621 OUTST2 06227 4594 4615* OUTST3 06230 4612 4616* OUTSTR 06200 1588 1760 1968 4586* 4628 5766 PAC1 6215 57 PACK 10500 6077 6129 6199* PACK1 10503 6204* 6234 PARMAP 00020 1378* 3092 3123 4151 6824 7304 7346 7379 7412 PARSDX 03413 3533 3543* PCCHK1 04160 3987* 3989 PCNAME 13714 1980 8224* PCOMP 04013 3873* 8125 PCOPY 04022 3880* 8121 PCOPY0 04041 3878 3897* PCOPY1 04044 3902* 3926 3928 PCOPY3 04061 3917* PCOPY4 04076 3920 3931* PCOPYE 04116 3876 3952* PCOPYW 04102 3894 3937* PEX 6004 2685 PGMDSP 06077 4488 4519* PGO 6003 2602 2643 PJ0F2 20100 8432* 8435 8437 8470 8724 8730 8733 8830 8833 8838 8902 8908 8971 8976 9001 PJ1F2 20117 8448* 8451 8453 8634 PM1MSG 14065 3117 8249* PM2MSG 14072 3121 8250* PMALL 02641 3072 3106* 3112 PMEDI1 02637 3078 3101* PMEDIT 02600 3070* 8119 PMSHOW 02652 3085 3107 3116* PNLBUF 12200 3168 3213 3582 3654 3903 3938 3956 7579* PNLCDF 07671 5702 5711* PNLMEM 00037 1392* 1787 1859 2033 2110 2151 2217 2274 2373 2571 3373 PNLTRP 07653 5643 5697* POP1 6235 57 POPJ1 10305 4175 5977* POST 6440 794* 950 960 1065 1094 1195 1204 1233 2672 5633 PPC1 6205 57 PR0 6206 5718 PR0MSG 13560 5732 8210* PR3 6236 795 PRCR 6473 776* PRISLU 6412 770* 8599 PRNMSG 13612 5724 8212* PROCEE 02207 2613* 8089 PROGLP 12655 7963* 7988 PROMPT 00141 1478* 5268 5274 5313 PRPA 6470 773* 6750 7256 PRPB 6471 774* 6753 7253 7529 PRPC 6472 775* PRS 6000 2674 5640 PSDISP 06064 4502* PSNAME 13730 1994 8228* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 257 Symbol Table BTS6120.PLX PUSHAC 04417 4168 4178 4182* PUSHAC2 20020 8416* 8433 8444 8449 8460 PUSHJ1 04400 1462 4167* 4169 4171 PWCR 6477 780* 6671 6674 6680 6740 6749 6757 6766 6770 7179 7195 7197 7209 7211 7221 7245 7252 7263 7275 7277 7484 7495 7497 7503 7522 7527 7533 PWPA 6474 777* 7193 PWPB 6475 778* 7188 7493 PWPC 6476 779* 6672 6742 7181 7247 7487 7525 PWRON 07634 5657* R3L 7014 832 951 4730 5089 6447 7767 7786 8791 8921 8939 8956 RAL 7004 823 827 2156 4294 4312 4993 4996 4997 5042 5641 5646 6410 6443 6788 7011 7044 8957 RAM128 1240 6034* 6420 7119 7120 RAM512 5200 6033* 7119 RAMBAS 00034 1387* 4152 6413 8499 8540 RAMBUF 10026 5808* 6164 6167 6169 6175 6179 6181 6185 6206 6208 6216 6218 6220 6224 6225 6229 RAMCDF 10743 6160 6214 6450 6473* 6475 7094 8628 RAMDAR 10031 5809* 6394 6400 6423 RAMDRD 10407 3339 3529 6111* RAMDRW 10307 5939 6058* RAMDWR 10420 3330 3622 6123* RAMER1 10431 6068 6113 6125 6133* RAMER2 10433 6073 6116 6128 6137* RAMINIT 04200 1238 3997* RAMMS1 14240 1273 8263* RAMMS3 14245 1278 8264* RAMPTR 10010 5793* 6162 6165 6168 6217 6219 6230 6408 6409 6411 6415 8630 RAMSEL 10712 3319 6066 6111 6123 6434* 7091 RAMSIZ 10043 5812* 7076 7138 7141 7152 RAMUSZ 10045 3327 3336 5814* 6385 6419 6464 6465 RANGE 06441 1454 4139 4804* 8734 RANGE1 06465 4808 4824* RAR 7010 818 819 3152 3222 4490 4493 4496 4717 4765 5892 6781 7008 7041 8740 8819 8998 RDADDR 06416 1862 2108 4773* 4779 4787 RDBFAI 00307 1285 1289* RDBOOT 10400 2985 6093* RDCH10 10614 6326 6337* RDCH11 10644 6358 6365* RDCH12 10651 6329 6350 6362 6370* RDCHK1 10603 1271 6317* RDDUMP 03400 3529* 8107 RDF 6214 1027 1074 1154 8491 8535 RDHIGH 06423 4779* 4811 RDIBU1 11656 7251* 7268 RDIBU2 11700 7274* 7279 RDIBU3 11706 7266 7284* RDIBUF 11646 6865 7241* RDLOW 06432 4787* 4804 RDMEM 01316 1457 2042* 2069 RDPAGE 10025 1473 5807* 6060 6080 6099 6384 6395 7702 RDPMLOC 7700 8485* 8500 8541 RDPMS1 0136 8487* 8508 8552 RDPMS2 0266 8488* 8512 8554 RDPS0 20230 8520* 8529 RDPSS 20201 4005 8490* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 258 Symbol Table BTS6120.PLX RDPSX 20240 8493 8510 8514 8531* RDPTR 03467 3530 3538 3585* RDRW1 10323 6071* 6082 RDRW2 10335 6076 6079* RDRW3 10337 6078 6080* RDSIZE 10033 5811* 6460 6505 7081 RDTES0 11456 7091* 7151 RDTES1 11510 7105 7123* RDTES2 11525 7128 7144* RDTEST 11446 1275 7076* RDTYPE 10046 5815* 6370 7145 RDUNIT 10024 3316 3548 3640 5806* 6065 6098 6435 6442 6459 6498 6499 6504 7080 7084 7144 7149 7701 RDYTMO 11424 7004 7005 7017 7019 7027* RECCNT 00072 1429* 3552 3567 3577 3594 RECSIZ 00071 1428* 3151 3169 3186 3214 3221 3251 3288 3323 3532 3540 3583 3588 3625 3633 3646 3655 4101 REGCMD 0107 6636* 6729 6860 6892 6918 6928 REGCNT 0102 6630* 6977 REGDAT 0100 6628* 6741 7180 7246 REGERR 0101 6629* 7056 REGLB0 0103 6631* 6945 REGLB1 0104 6632* 6957 REGLB2 0105 6633* 6962 REGLB3 0106 6634* 6684 6972 REGLSC 01240 1890 1960* 2580 5772 REGLST 01224 1951* 1960 REGSTS 0107 6635* 6687 7007 7040 REPCNT 00063 1418* 1533 1553 1556 1650 1657 REPEA1 00615 1640 1649* REPEAT 00600 1638* 8053 REPLOC 00064 1419* 1557 1654 1655 RESTA 00400 1459 1515* 1573 4140 RET0F2 04302 4110* 8441 RET0F3 04304 4113* 4121 RET1F2 12471 7851* 8457 RET1F3 12473 7854* 7863 RET2F3 20501 8697* 8706 RFNS 6434 787* 4253 4277 4454 4489 RFRMAT 03120 3314* 8115 RLLOAD 03513 3622* 8111 RLOF 6435 788* 1519 4235 5750 5763 RLON 6437 789* 2671 ROMCH0 10062 1069* 1071 ROMCH1 10076 1076 1081* ROMCHK 10060 1067* 1080 ROMCK0 00200 1182* 1723 ROMCK1 10200 1726 5834* ROMCK2 20200 1730 8480* ROMCP0 10036 1019* 1034 ROMCP1 10056 1029 1035* ROMCPY 10040 964 966 967 968 977 978 979 980 981 982 983 984 985 986 987 988 1021* 1026 ROMWR 12600 4098 7902* RSP1 6207 2669 5616 RSP2 6227 5618 RTF 6005 2683 RTL 7006 816 821 828 829 2720 4302 4307 4605 4713 4714 5041 5647 6177 6182 6183 6786 6787 6952 6953 7259 7956 8940 RTN1 6225 57 RTR 7012 817 820 830 2719 4610 4766 6223 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 259 Symbol Table BTS6120.PLX 6227 6228 6782 6948 6959 6960 7191 7905 7906 8739 8818 8853 8997 RWCNT 10054 5824* 6081 7445 7454 7564 7584 SAVCHR 00050 1401* 1624 1625 2277 2281 2797 3787 3797 3832 4532 4536 4564 4715 4716 4719 4999 5044 5119 5120 5125 5281 5285 5298 5300 SBBLO 6415 6039* 6366 SCAN 20010 8408* 8641 8643 8647 8677 8856 8858 8898 SCCOM 00670 1706* 8131 SCOPE 00032 1381* 1709 5363 SCPT 6433 786* 5676 SEAR1 01633 2279 2283 2290* SEAR2 01640 2297* 2311 SEAR3 01656 2302 2307* SEAR4 01665 2309 2314* SEARCH 01600 2263* 8071 SETBUF 12123 6058 7403 7552* SETDA1 10663 6396* 6401 SETDA2 10671 6399 6406* SETDAR 10654 6071 6114 6126 6383* SETDRD 0007 6615* 6748 6765 7251 7274 7526 SETDRE 0013 6619* 6673 SETDWR 0011 6617* 7194 7208 7494 SETLBA 11310 6857 6889 6942* SETPMP 11732 5944 7337* SHSW 6431 784* 5669 SICOM 02144 2561* 8091 SIMFLG 00047 1400* 2605 2642 5752 SINGLE 02202 2576 2602* 2614 SIZPTR 10044 5813* 6461 6462 6506 6507 7125 7126 SKP 7410 1211 1226 1648 1784 1856 3178 3243 3919 5670 7199 7265 7446 8777 9020 SKPMSG 13475 2823 8202* SMA 7500 1284 1601 1673 1697 2806 4919 4926 4988 5034 5296 5400 6075 7146 7422 SNA 7450 1028 1075 1282 1314 1531 1538 1548 1606 1609 1612 1619 1639 1656 1667 1691 1758 1826 1871 1889 2034 2072 2173 2221 2278 2282 2342 2387 2419 2424 2467 2483 2512 2540 2708 2798 2916 2952 3071 3084 3388 3425 3451 3556 3571 3763 3767 3781 3971 4220 4251 4258 4287 4452 4484 4534 4618 4638 4649 4694 4895 4953 4957 5011 5054 5117 5127 5130 5198 5279 5290 5334 5343 5346 5367 5397 5439 5521 5716 5720 6275 6325 6357 6421 6467 7015 7127 7139 7560 7598 7826 7829 7942 7947 7974 7979 8468 8610 8662 8727 8773 8867 8871 8877 8991 SNCOM 02200 2591* 8085 SNL 7420 1791 2106 2148 2430 2474 2972 2975 3029 3888 4093 4684 4898 4907 6398 7763 7791 8946 8958 SP1NAM 13733 1999 8229* SP2NAM 13737 2004 8230* SPA 7510 1253 1554 1619 1670 1694 4300 4305 4310 4313 4841 4985 5031 5096 5202 5218 5287 5443 5642 5648 7129 SPACM0 06103 1448 4133 4531* SPACMP 06101 1447 4132 4528* 4535 8725 SPANXT 06121 1905 4559* SPATST 06123 1863 3867 4563* SPD 6276 961 1099 1111 1187 1518 2032 2047 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 260 Symbol Table BTS6120.PLX 2058 2922 4234 4381 5631 5710 5927 6187 6209 7219 7285 7633 7648 7670 7744 7775 7792 8721 8758 9025 SPINDN 11303 6925* SPINUP 11276 6915* SPLK 6432 785* 4257 4456 SRCCDF 12262 7630 7660* 7667 SRCDAR 0024 7701* 7707 7728 SRCSPD 12263 7634 7661* SRNAME 13725 2009 8227* STA 7240 1095 1221 1552 1646 1783 1855 2117 2213 2268 2272 2305 2604 2774 3755 4215 4416 4573 5206 5216 5359 5375 5551 5697 6093 6818 7140 7840 STACK 0177 1189 1482* 1483 1521 START 02251 2707* 8087 START1 02275 2709 2726* STARTXROM 20462 8663 8673* STKLEN 0034 1483* 1484 STKSAV 00142 1481* 2670 5627 STL 7120 827 829 830 2398 2923 4917 5136 6138 7057 7825 8026 STSBSY 0200 6639* 7012 7045 STSCOR 0004 6644* STSDF 0040 6641* STSDRQ 0010 6643* 7045 7046 STSDSC 0020 6642* STSERR 0001 6645* STSRDY 0100 6640* 7012 7013 SWBOO1 06014 4411 4416* SWBOOT 06007 4296 4410* SWCLR 06017 4306 4425* SWDEP 05725 4314 4350* SWEXA 05735 4311 4363* SWEXA1 05741 4356 4366* SWLA 05702 4301 4325* SWLXA 05711 4304 4335* SWP 7521 7737 7771 7779 SWPADR 06521 2113 2120 4866* SWSCA1 05634 4270* 4272 SWSCAN 05621 1529 4250* SWTEMP 05701 4279 4282 4284 4318* SYSCRN 14164 1737 8260* SYSIN2 00201 1131 1186* SYSIN3 00235 1233* SYSIN4 00346 1305 1309 1330* SYSIN5 00350 1321 1327 1332* SYSIN7 00343 1315 1325* SYSIN9 00352 1338* 4125 SYSINI 10001 950* 5595 SYSNM1 14117 1718 8257* SYSNM2 14136 1722 8258* SYSNM3 14146 1734 8259* SZA 7440 953 970 1072 1107 1115 1150 1223 1673 1697 1813 1829 1874 2301 2315 2352 2391 2396 2820 2924 3049 3077 3111 3189 3230 3235 3254 3380 3403 3433 3500 3712 3719 3789 3795 3799 3815 3818 3830 3833 3925 4059 4074 4080 4271 4457 4487 4550 4566 4807 4856 4988 5034 5148 5307 5322 5331 5349 5364 5405 5411 5460 5463 5526 5536 5549 5557 5753 6349 6677 6689 6849 6881 7048 7104 7118 7150 7832 7918 7926 8011 8509 8513 8645 8649 8768 8893 9011 SZL 7430 1304 1308 1808 2116 2124 2157 2164 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 261 Symbol Table BTS6120.PLX 2231 2308 2961 2987 3000 3172 3217 3320 3586 3658 3911 3946 3964 4295 4303 4308 4491 4494 4497 4818 5644 5875 6067 6072 6112 6115 6124 6127 6386 6437 6445 6502 6725 6731 6855 6862 6887 6894 7009 7042 7343 7376 7450 7632 7647 8787 8794 8994 TAD 1000 952 963 965 967 968 977 979 981 983 985 987 1022 1030 1069 1077 1113 1138 1142 1147 1149 1155 1189 1234 1251 1252 1258 1280 1312 1319 1521 1527 1537 1540 1544 1546 1547 1553 1557 1570 1587 1599 1600 1605 1607 1608 1610 1611 1613 1614 1618 1620 1621 1625 1647 1653 1655 1666 1669 1672 1675 1690 1693 1696 1699 1708 1719 1723 1726 1730 1753 1756 1795 1798 1800 1811 1828 1867 1873 1894 1908 1916 1921 1926 1931 1934 1941 1967 1969 1973 1978 1983 1992 1997 2002 2019 2021 2033 2044 2046 2056 2067 2071 2079 2121 2155 2161 2172 2180 2197 2215 2228 2264 2270 2277 2281 2285 2291 2300 2314 2337 2339 2341 2351 2365 2367 2369 2371 2386 2390 2393 2395 2423 2432 2466 2482 2491 2493 2495 2497 2511 2515 2519 2539 2543 2545 2564 2567 2569 2676 2678 2680 2682 2684 2716 2718 2721 2794 2797 2804 2805 2813 2819 2826 2910 2915 2920 2959 2966 3024 3026 3031 3047 3075 3079 3091 3092 3094 3109 3110 3118 3122 3123 3125 3151 3154 3157 3159 3169 3186 3214 3221 3224 3227 3229 3232 3233 3251 3265 3287 3292 3298 3322 3327 3330 3336 3339 3376 3379 3387 3390 3395 3401 3407 3411 3415 3423 3424 3427 3428 3429 3431 3437 3444 3449 3453 3461 3463 3486 3529 3531 3537 3539 3545 3547 3561 3563 3575 3583 3588 3603 3622 3624 3630 3632 3639 3641 3646 3650 3655 3684 3690 3694 3701 3704 3705 3707 3710 3717 3718 3721 3752 3760 3765 3766 3778 3780 3785 3787 3788 3792 3794 3797 3798 3805 3808 3809 3813 3827 3829 3832 3837 3865 3869 3876 3885 3894 3904 3908 3921 3939 3943 3957 3961 3970 3978 3982 3984 3987 3997 4035 4038 4040 4043 4046 4048 4051 4054 4056 4058 4062 4065 4067 4073 4077 4079 4087 4098 4100 4169 4171 4175 4178 4219 4232 4250 4256 4269 4280 4284 4338 4366 4368 4379 4392 4394 4429 4451 4483 4486 4503 4510 4515 4519 4532 4533 4536 4564 4565 4574 4586 4600 4602 4607 4615 4627 4637 4647 4660 4663 4669 4679 4683 4690 4693 4708 4712 4716 4719 4756 4758 4774 4780 4782 4788 4790 4806 4812 4814 4824 4826 4839 4840 4843 4853 4855 4858 4860 4867 4869 4873 4875 4900 4909 4910 4918 4921 4925 4928 4952 4956 4963 4984 4987 4992 4995 4998 4999 5000 5010 5030 5033 5038 5040 5044 5045 5053 5082 5088 5094 5095 5100 5120 5125 5126 5129 5146 5154 5159 5164 5169 5174 5178 5190 5197 5201 5210 5217 5221 5269 5274 5285 5286 5289 5294 5295 5298 5300 5306 5310 5313 5315 5321 5324 5330 5333 5342 5345 5348 5353 5357 5363 5366 5370 5376 5399 5404 5410 5413 5419 5422 5426 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 262 Symbol Table BTS6120.PLX 5438 5442 5459 5462 5495 5525 5530 5535 5539 5542 5548 5556 5564 5627 5698 5700 5702 5706 5708 5714 5715 5718 5752 5765 5767 5770 5872 5874 5877 5878 5880 5887 5896 5916 5920 5922 5926 5967 6063 6074 6095 6152 6162 6165 6168 6175 6179 6181 6185 6200 6205 6207 6216 6218 6220 6225 6229 6263 6267 6273 6302 6323 6337 6341 6343 6345 6346 6354 6356 6384 6385 6395 6397 6406 6409 6411 6413 6419 6420 6422 6423 6435 6436 6442 6444 6449 6459 6460 6462 6465 6499 6501 6504 6505 6507 6670 6673 6675 6679 6682 6688 6727 6735 6737 6739 6741 6748 6756 6763 6765 6769 6780 6785 6790 6809 6820 6824 6828 6848 6858 6864 6880 6890 6896 6916 6926 6943 6946 6951 6955 6958 6970 7003 7013 7046 7079 7081 7092 7096 7098 7100 7101 7111 7114 7116 7119 7120 7126 7130 7131 7138 7145 7147 7148 7149 7152 7176 7178 7180 7185 7187 7189 7194 7196 7208 7210 7220 7242 7244 7246 7251 7260 7262 7274 7276 7302 7304 7308 7340 7342 7345 7346 7348 7374 7375 7378 7379 7382 7410 7412 7415 7421 7423 7424 7448 7459 7483 7485 7492 7494 7496 7502 7521 7523 7526 7532 7534 7554 7556 7558 7566 7579 7581 7597 7627 7629 7631 7633 7636 7642 7644 7646 7648 7651 7662 7705 7709 7714 7718 7728 7730 7735 7762 7773 7775 7777 7784 7788 7790 7792 7794 7823 7831 7838 7904 7911 7913 7916 7924 7925 7935 7937 7940 7945 7949 7954 7960 7964 7967 7972 7977 7981 7990 7995 7998 7999 8002 8007 8010 8021 8023 8435 8437 8441 8444 8451 8453 8457 8460 8467 8492 8495 8499 8500 8507 8508 8511 8512 8516 8522 8524 8536 8540 8541 8544 8552 8554 8557 8560 8565 8609 8623 8627 8632 8643 8644 8647 8648 8656 8658 8674 8717 8721 8738 8742 8745 8748 8749 8751 8755 8765 8767 8770 8772 8778 8779 8785 8788 8789 8792 8795 8796 8808 8810 8812 8814 8817 8829 8832 8835 8837 8840 8851 8855 8858 8861 8865 8870 8875 8882 8884 8898 8907 8917 8920 8923 8926 8928 8931 8934 8938 8943 8955 8961 8964 8970 8973 8975 8978 8990 8993 8996 9000 9010 9013 9023 TADDR 06400 1804 1835 2078 4755* TASCI1 06247 4637* 4641 TASCIZ 06246 1571 4636* 5316 TASZF1 06255 1320 4645* 4652 TASZF2 20136 8466* 8472 8836 8841 8962 8974 8979 9014 TBACKS 07131 1437 5216* TBELL 07071 5163* 5205 5381 TCF 6042 767* 1209 TCKSUM 01472 2172* 3465 TCKSUN 01477 2165 2174 2178* TDECN1 06302 4682* 4687 TDECN2 06310 4685 4690* TDECN3 06320 4695 4699* TDECNW 06277 1443 4142 4677* 4696 TDIGIT 07102 3119 4700 4721 4768 5178* TDOT 07077 1444 5173* TFCHA1 07445 5457* 5464 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 263 Symbol Table BTS6120.PLX TFCHA2 07460 5461 5471* TFCHAR 07444 5165 5191 5211 5222 5420 5456* TFIELD 06412 4757 4765* 5769 TFILV 00646 1671 1674 1682* 1695 1698 THCHA1 07443 5440 5444 5446* THCHAR 07427 4670 5155 5160 5170 5175 5179 5414 5423 5435* TLS 6046 769* 1206 1213 5496 TMEM 01060 1819 1835* 2303 2344 4371 TOCT3 06343 1442 4730* TOCT4 06322 1438 4130 4707* 4736 4740 4743 8834 8839 8972 8977 TOCT4C 06352 1439 4740* TOCT4M 06355 1440 4743* TOCT4S 06347 1441 4736* TOCTL 06325 4712* 4725 TOCTN 06324 4709* 4733 TPC 6044 768* TPCOM 00650 1688* 8097 TPCOM1 00666 1692 1700* TQUEST 07066 1569 1572 1586 2175 5115 5158* TRACE 02146 2564* 2637 TRAP 07720 5657 5687 5723 5727 5731 5755 5762* 5765 TRPMSG 13636 5658 8214* TSF 6041 766* 1207 1210 1214 2753 5493 TSIXB 21062 8888 8890 8906* TSIXC 06274 4662 4668* TSIXW 06266 4659* TSLASH 07074 3696 4760 5168* TSPACE 07063 1436 5145 5153* TSTADR 06506 1455 4816 4852* TTABC 07054 5145* 5149 5407 TWCOM 00625 1664* 8095 TWCOM1 00643 1668 1676* TWCOM2 00644 1677* 1701 1710 TYPEAC 01252 1954 1973* 8159 TYPEIR 01263 1988* 2579 4144 TYPEMQ 01260 1955 1983* 8163 TYPEPC 01255 1952 1978* 4328 8161 TYPEPS 01265 1953 1992* 4343 8165 TYPESR 01276 2007* 8167 TYPRG4 01243 1965* 1967 1974 1979 1984 1993 1998 2003 2008 TYPSP1 01270 1956 1997* TYPSP2 01273 1957 2002* UAC 00001 1359* 1917 1973 2684 2768 4123 4428 4510 5611 5887 5891 7838 UFLAGS 00002 1360* 1934 1937 1992 2564 2682 2722 2770 4124 4338 4341 4368 4392 4429 4431 4503 5082 5088 5613 5700 5767 5895 5897 5920 8810 UIR 00007 1365* 2573 4145 5709 5714 8812 UIRPC 00006 1364* 2570 5707 8808 UMQ 00003 1361* 1927 1983 2680 2769 4427 4515 5615 UNPAC1 10441 6160* 6190 UNPACK 10436 6079 6117 6151* 8635 UNPLP 20430 8634* 8637 UPC 00000 1358* 1922 1978 2567 2569 2686 2717 2775 2967 4122 4326 4353 4354 4363 4366 4379 5698 5699 5706 5708 5770 5916 5918 UPDIS1 06066 4504* 4511 4516 4520 UPDIS2 06067 4492 4505* UPDISP 06044 4483* 5499 5518 5678 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 264 Symbol Table BTS6120.PLX USERDF 06000 4350 4377 4391* USP1 00004 1362* 1997 2676 2771 4425 5617 USP2 00005 1363* 2002 2678 2772 4426 5619 VALUE 00044 1397* 1966 1969 2045 2046 2053 2056 2121 2210 2228 2334 2346 2351 2816 2826 3025 3026 3031 3418 3437 3444 3461 3600 3603 3703 3704 3707 VECOM 00677 1716* 8093 VERSION 0266 751* 1719 4232 5967 8679 VMAMSG 14105 2990 8253* VPOS 00054 1407* 5195 5201 5204 5284 5560 5632 WDRQ 11426 6730 6861 6893 7039* 7049 WFRDY1 12632 7939* 7943 WFRDY2 12664 7971* 7975 WIDTH 00030 1379* 1676 3998 5438 WORD 00065 1422* 1545 1546 1647 1666 1690 1708 1867 1916 1921 1926 1931 1941 2197 2264 2285 2423 2466 2716 2794 2796 2813 3024 3075 3079 3094 3391 3401 3407 3422 3423 3449 3453 3457 3545 3547 3561 3563 3575 3639 3641 3778 3785 3792 3805 3808 3827 3865 3869 4659 4660 4663 4677 4679 4707 4712 4718 4731 4774 4979 4992 4994 4995 4998 5001 5025 5038 5040 5046 WORDH 00066 1423* 5039 5100 WREAD1 11403 7006* 7018 7020 WREADY 11400 6690 6724 6854 6886 6905 6919 6929 7003* WRIBU1 11610 7185* 7202 WRIBU2 11632 7208* 7213 WRIBU3 11640 7200 7218* WRIBUF 11600 6897 7175* WRMEM 01330 2053* 2068 WRPS0 20266 8563* 8577 WRPSS 20243 1678 3097 7352 8535* WRPSX 20303 8537 8581* WRPTR 03554 3623 3631 3657* 4099 WSR 6246 1942 4504 X1 00010 1369* 2337 2366 2386 2432 2443 2482 2491 2511 2539 2911 2915 3093 3095 3124 3125 3155 3158 3161 3225 3229 3232 3685 3701 3753 3807 3983 3987 4587 4600 4601 4602 4607 4615 4636 4637 4645 4647 4948 4952 4959 4963 X2 00011 1370* 2339 2368 2393 2402 2444 2481 2495 2515 2524 2543 2550 2913 2920 X3 00012 1371* 1754 1756 2370 2445 2518 2525 2545 2551 XCMDDN 20710 8774 8800* XCOMM 20605 8718 8722* XCT1 02340 2799 2804* XCT2 02346 2807 2812* XCT3 02360 2821 2824* XCTBLK 02350 2795 2804 2814* XCTCOM 02324 2793* 8099 XDSCDF 12330 7709 7732* XFRCNT 10051 5821* 6153 6189 6201 6233 6738 6758 6764 6771 7177 7198 7212 7243 7264 7278 7657 7666 7723 7739 XIR 20004 8403* 8756 8813 8837 8851 8861 8865 8934 8938 8955 8996 XOFF 00052 1405* 5207 5272 5282 5462 5529 5538 5552 5559 XPC 20003 8402* 8746 8755 8809 8832 8943 XRCHECK 20453 8658* 8660 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 265 Symbol Table BTS6120.PLX XRMES1 14332 1257 8275* XROMERR 20475 8666 8689* XSRCDF 12321 7705 7725* 7740 XTYPIR 20712 1989 8808* XX1 10012 5795* 7082 7083 7305 7310 7347 7350 7380 7382 7413 7415 7637 7662 7715 7730 7759 7774 7776 7778 7789 7793 7795 7961 7967 7996 8007 XX2 10013 5796* 7652 7665 7719 7738 8000 8010 8021 ZBACKS 00076 1437* 5336 5338 ZBACKUP 00112 1449* 1641 1824 1891 2223 2421 2712 2954 3073 3086 3558 3573 4908 5317 5369 5374 ZCOMERR 00125 1460* 1830 1875 2107 2149 2425 2468 3784 3790 3796 3800 3819 3834 4551 4567 4899 5012 5055 ZCRLF 00106 1244 1260 1291 1332 1445* 1523 1735 1738 1739 1761 1815 1823 1896 1961 2304 2345 2991 3004 3261 3305 3716 3934 3974 4329 4344 4372 4412 4741 4744 5122 5312 5326 5355 5445 5541 5764 ZDANDV 00123 1458* 1868 2122 2229 2520 2546 3438 ZDKRBN 00137 1474* 3147 3181 3207 3246 3265 3549 3562 3591 3649 3650 3690 3898 3978 ZEOLNXT 00114 1451* 1716 1893 2332 2561 2591 2613 2631 2738 2956 3372 ZEOLTST 00113 1450* 1643 1665 1689 1707 1752 1907 2109 2150 2225 2287 2470 2714 2801 3021 3088 3578 3637 3871 ZERROR 00126 1461* 1682 2131 2317 2354 2438 2476 2487 2808 2979 3035 3051 3101 3841 4820 ZGET 00115 1452* 2208 2418 2707 3817 4528 4545 4559 4905 5005 5048 ZINLMES 00107 1256 1272 1277 1286 1289 1300 1317 1325 1330 1446* 1717 1721 1733 1736 2076 2178 2822 2824 2989 3002 3022 3116 3120 3144 3204 3262 3303 3601 3874 3883 3892 3932 3975 4083 4090 ZK177 00130 1465* 2921 4616 5520 ZK7 00132 1467* 1800 1812 3711 3814 4720 4767 5147 ZK70 00131 1466* 2020 2215 2270 2565 3454 4369 4393 4844 5083 5090 5102 5701 5768 ZK7400 0135 1472* 4603 4608 ZK7600 0134 1470* ZM128 00134 1469* 1470 3322 3531 3624 ZM256 00135 1471* 1472 3287 3539 3632 3908 3921 3943 3961 4100 ZMSPACE 00133 1468* 4533 4565 4900 4909 5286 5399 ZNXTADR 00121 1456* 1810 1869 2119 2123 2166 2233 2310 ZOCTNW 00116 1453* 1866 1906 2196 2263 2284 2793 2800 3020 3074 3087 3543 3559 3574 3636 3777 3791 3804 3826 3864 3868 5092 ZOUTCHR 00074 1435* 3505 4620 4640 4651 5121 5275 5299 5311 5314 5325 5354 5371 5531 5540 ZPUSHJ1 00127 1270 1274 1302 1306 1462* 2760 2984 2997 3167 3170 3212 3215 3318 3581 3584 3653 3656 3902 3909 3937 3944 3955 3962 4002 ZRANGE 00117 1454* 1790 2105 2147 2224 2280 ZRDMEM 00122 1457* 1805 1836 2081 2114 2160 2298 2517 2572 ZRDPAGE 00136 1473* 3148 3182 3208 3247 3550 3564 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 266 Symbol Table BTS6120.PLX 3592 3651 ZRESTA 00124 1338 1459* 1589 3030 3506 3889 4085 4094 4745 5532 5775 ZSPACM0 00111 1448* 1870 2220 3083 3555 3570 4549 4805 ZSPACMP 00110 1447* 1638 1825 1888 2951 3070 4894 4981 5027 ZTDECNW 00104 1259 1276 1316 1443* ZTDOT 00105 1444* 3191 3256 3693 3927 ZTOCT3 00103 1442* 1720 3695 ZTOCT4 00077 1438* 3692 4759 ZTOCT4C 00100 1439* 2181 2827 3126 3267 3722 3980 5771 ZTOCT4M 00101 1440* 2082 3604 ZTOCT4S 00102 1441* 1724 1728 1732 1806 1837 1970 2080 3027 3708 3886 ZTSPACE 00075 1436* 3697 4737 4761 5337 ZTSTADR 00120 1455* 1807 2115 2163 2230 2307 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 13-JAN-24 18:41:12 Page 267 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 13-JAN-24 18:41:12 Page 268 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 13-JAN-24 18:41:12 Page 269 Table of Contents BTS6120.PLX Get Arguments for MEMMOV Calls . . . . . . . . . . . . . . . . 194 LIGHTS Monitor Call . . . . . . . . . . . . . . . . . . . . . . 195 Field 1 Vector Table . . . . . . . . . . . . . . . . . . . . . 196 Flash ROM erasure and writing . . . . . . . . . . . . . . . . . 197 Free Space for Future Expansion! . . . . . . . . . . . . . . . 200 Command Names Table . . . . . . . . . . . . . . . . . . . . . . 201 Argument Tables for Various Commands . . . . . . . . . . . . . 203 Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 Help Text . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 Temporary Disk Buffer . . . . . . . . . . . . . . . . . . . . . 209 Field 2 Variables . . . . . . . . . . . . . . . . . . . . . . . 210 Field 2 Cross Field Linkages . . . . . . . . . . . . . . . . . 211 Persistent setting support (NVRAM) . . . . . . . . . . . . . . 212 Extension ROM management . . . . . . . . . . . . . . . . . . . 214 Field 2 Vector Table . . . . . . . . . . . . . . . . . . . . . 216 X / XP Commands -- Disassemble memory . . . . . . . . . . . . . 217 Disassemble Current Trace Location . . . . . . . . . . . . . . 219 Disassembler Top Level . . . . . . . . . . . . . . . . . . . . 220 Disassemble EA For MRIs . . . . . . . . . . . . . . . . . . . . 222 Disassemble OPR and IOT instructions . . . . . . . . . . . . . 224 Disassembler Tables (MRIs) . . . . . . . . . . . . . . . . . . 225 Disassembler Tables (IOTs) . . . . . . . . . . . . . . . . . . 226 Disassembler Tables (OPRs) . . . . . . . . . . . . . . . . . . 229 Disassembler Messages . . . . . . . . . . . . . . . . . . . . . 232 Free Space for Future Expansion! . . . . . . . . . . . . . . . 233 Memory Map . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Symbol Table . . . . . . . . . . . . . . . . . . . . . . . . . . 240