Site logo 14114

<REFERENCE>PRIME>DRB>FASTCONSOLE


How to patch ASRDIM for fast console output in the emulator

(Based on a note by Jim Wilcoxson)

What you need to know

  • Octal math

The concept here is construct a patch which overlays segment 6 after PRIMOS has booted. This patch is loaded over the top of segment 6 using the PRIMOS SHARE command. That means that besides the two words that typically need to be patched, it must contain the original contents of segment 6 for all other words in between the two in question.

The structure of ASRDIM, the console terminal driver, is more or less the same for at least PRIMOS revisions 18-21. At Rev22, ASRDIM was restructured somewhat. There are two paths through parts of these instructions to account for the differences.

Note that the VPSD debugger is a bit corkbrained. Left to its own devices, it will list several disassembled instructions across the screen. It also disassembles two word instructions oddly: the full instruction will be shown, then a disassembly of the disembodied second word will be shown. If you compare the source code of a similar version to the VPSD disassembly, you'll have to learn to skip over these bogons. I've opted to leave the bogons in the examples here, though that may be a mistake. Here's what it might look like:

Source code
-----------

COUT  LDX   =1
      LDA   P$TFLRPT,*X     ANY DATA IN OUTPUT BUFFER?
      SUB   P$TFLWPT,*X
      BNE   COUTA           YES, THERE IS OUTPUT
      LDX   ASROUT          ANY OUTPUT IN ALTERNATE OUTPUT BUFFER?

VPSD disassembly
----------------

4000/ 72210 LDX#  72435
4000/ 72211 LDA%  72410,*X
4000/ 72212 LDX# LB%+ 410       <-- bogus
4000/ 72213 SUB%  72412,*X
4000/ 72214 LDX# LB%+ 412       <-- bogus
4000/ 72215 BNE   72230
4000/ 72216 LDX# SB%+ 230

The process

  • Look up ASRDIM in RING0.MAP and record the second number:

    OK, a prirun
    OK, ed ring0.map
    EDIT
    l ASRDIM
      ASRDIM    0006  071262  OTHER
    q
    
  • Read PRIMOS' segment 6 image into RAM:

    OK, rest pr0006
    
  • Start the debugger to examine and change memory:

    OK, vpsd16
    $
    
  • Find address of COUT by examining 30 (octal) words starting at the address you located in the map:

    $d 71262 71311 1 :s
    4000/ 71262 EAL% XB%+ 0
    4000/ 71263 HLT
    4000/ 71264 STL%  71620
    4000/ 71265 JSY#  71106,X
    4000/ 71266 LDA#  71610
    4000/ 71267 BNE   72021
    4000/ 71270 LDX# SB%+ 21
    4000/ 71271 LDA#  71623
    4000/ 71272 BEQ   71306
    4000/ 71273 JSY#  71602,X
    4000/ 71274 LDA#  71624
    4000/ 71275 EIO%  170004
    4000/ 71276 JSY#  4,X*
    4000/ 71277 BCNE  71672
    4000/ 71300 JSY#  71173,X
    4000/ 71301 CRA
    4000/ 71302 IMA#  71623
    4000/ 71303 S2A
    4000/ 71304 BEQ   71763
    4000/ 71305 JSY#  71271,X
    4000/ 71306 LDA#  71353
    4000/ 71307 EIO%  130004
    4000/ 71310 JSY#  4,*
    4000/ 71311 BCNE  71641         <-- Branches to COUT, record this address
          ^
          |
          +------- The second column is the address
    
  • For Revisions 22 - 24, now examine 100 (octal) words starting at the address of COUT that you recorded above:

    $d 71641 71741 1 :s
    4000/ 71641 LDA#  71612
    4000/ 71642 SAR  4
    4000/ 71643 JMP#  71672
    4000/ 71644 EAXB%  72102,*
    4000/ 71645 LDX# SB%+ 102
    4000/ 71646 LDX#  71674
    4000/ 71647 LDA% XB%+ 3
    4000/ 71650 DAC   3
    4000/ 71651 SUB% XB%+ 2
    4000/ 71652 DAC   2
    4000/ 71653 BNE   71675
    4000/ 71654 JSY#  71552,X
    4000/ 71655 FLX%  71611
    4000/ 71656 JSY#  71470,X
    4000/ 71657 EAXB%  72100,*X
    4000/ 71660 LDX# SB%+ 100
    4000/ 71661 EAXB% XB%+ 177776,*
    4000/ 71662 DIV#  71661,*X
    4000/ 71663 LDX#  71611
    4000/ 71664 LDA% XB%+ 3
    4000/ 71665 DAC   3
    4000/ 71666 SUB% XB%+ 2
    4000/ 71667 DAC   2
    4000/ 71670 BNE   71675
    4000/ 71671 JSY#  71567,X
    4000/ 71672 JMP%  71620,*
    4000/ 71673 JSY#  71514,X
    4000/ 71674 NOP
    4000/ 71675 EIO%  70604
    4000/ 71676 JSY# LB%+ 604,X
    4000/ 71677 BCNE  71672
    4000/ 71700 JSY#  71573,X
    4000/ 71701 STX#  71626
    4000/ 71702 EAXB%  72102,*
    4000/ 71703 LDX# SB%+ 102
    4000/ 71704 LDA% XB%+ 20
    4000/ 71705 DAC   20
    4000/ 71706 BGE   71720
    4000/ 71707 JSY#  71630,X
    4000/ 71710 CHS
    4000/ 71711 BEQ   71716
    4000/ 71712 JSY#  71631,X
    4000/ 71713 LDA#  71715
    4000/ 71714 JMP#  71733
    4000/ 71715 DAC   200
    4000/ 71716 STA% XB%+ 20
    4000/ 71717 DAC   20
    4000/ 71720 LDA#  71674
    4000/ 71721 STA#  71627
    4000/ 71722 EAL%  71626
    4000/ 71723 JSY#  71552,X
    4000/ 71724 JSXB%  72056,*
    4000/ 71725 LDX# SB%+ 56
    4000/ 71726 CAS#  71630
    4000/ 71727 SKP
    4000/ 71730 JMP#  71764         <-- Note this address of TDELNL (here 71764)
    4000/ 71731 EAXB%  72102,*
    4000/ 71732 LDX# SB%+ 102
    4000/ 71733 IRS% XB%+ 20
    4000/ 71734 DAC   20
    4000/ 71735 RCB
    4000/ 71736 EIO%  170004
    4000/ 71737 JSY#  4,X*
    4000/ 71740 BCEQ  71672
    4000/ 71741 JSY#  71634,X       <-- Want to patch this word, note its address
    
  • For Revisions 18 - 21, we'll skip the TDELNL part, and the disassembly will look more like this:

    .
    .
    .
    4000/ 72261 IRS%  72414,*X
    4000/ 72262 LDX# LB%+ 414
    4000/ 72263 RCB
    4000/ 72264 EIO%  170004
    4000/ 72265 JSY#  4,X*
    4000/ 72266 JMP%  72375,*       <-- Want to patch this instruction
    
  • For Revisions 22 - 24, patch the word after BCEQ opcode above (in this example, at address 71741) to contain the address of COUT:

    $a 71741 :o
    4000/ 71741 71672 71641
    4000/ 71742 11661 /
    
  • For Revisions 18 - 21, assemble a new instruction at the location you found above (in this example, at address 72266) to contain a JMP to COUT:

    $a 72266
    4000/ 72266 43420 jmp 72210
    4000/ 72267 72375 /
    
  • For Revisions 22 - 24 only, now examine 30 (octal) words starting at the address of TDELNL that you recorded above:

    $d 71764 72014 1 :s
    4000/ 71764 STA#  71624
    4000/ 71765 EAXB%  72102,*
    4000/ 71766 LDX# SB%+ 102
    4000/ 71767 LDA% XB%+ 20
    4000/ 71770 DAC   20
    4000/ 71771 MPY% XB%+ 22
    4000/ 71772 DAC   22
    4000/ 71773 LLS  4
    4000/ 71774 ADD% XB%+ 21
    4000/ 71775 RMC
    4000/ 71776 SPL
    4000/ 71777 CRA
    4000/ 72000 CAS#  72020
    4000/ 72001 LDA#  72020
    4000/ 72002 RCB
    4000/ 72003 TCA
    4000/ 72004 STA% XB%+ 20
    4000/ 72005 DAC   20
    4000/ 72006 LDA#  71624
    4000/ 72007 EIO%  170004
    4000/ 72010 JSY#  4,X*
    4000/ 72011 BCEQ  71672
    4000/ 72012 JSY#  71705,X   <-- Want to patch this word, note its address
    4000/ 72013 LT
    4000/ 72014 STA#  71623
    
  • For Revisions 22 - 24 only, patch the address of the word after BCEQ instruction above (in this example, address 72012) to contain the address of COUT:

    $a 72012 :o
    4000/ 72012 71672 71641
    4000/ 72013 140417 /
    
  • Exit the debugger:

    $q
    
  • Save memory from the first patched word address to the second:

    OK, save asrdim.patch 71741 72012
                          ^     ^
                          |     |
                          |     +--- address of second word
                          +--- address of first word
    

For Revisions 18 - 21, save two words starting at the address where you patched in the JMP.

  • To use this patch:

    OK, share prirun>asrdim.patch 6
    
  • After doing this, test the system to make sure you didn't goof. If it seems to be working, you can place this share command in PRIMOS.COMI anywhere after the CONFIG command and it will execute at every boot.

  • It's possible that in some versions of PRIMOS, the branches targeted here might actually be further along in memory than the mentioned number of words above. If you're not finding the pattern of instructions shown, dump a little more.