8

From Gary B. Little's "Apple ProDOS: Advanced Features for Programmers", pages 176 - 188:

"Since the ONLINE command handler is not inherently relocatable, all references to internal absolute addresses must be altered to reflect the change in the position of the code."

I don't understand the address choices in the relocate routine:

STA CMDCODE+$0F and so on.

Why $0F,$1A,$32,$49,#4E,$55,$6F,$75,$8A,$A4,AND $D5. How are these "references to internal absolute addresses".

I'm not getting it and if anyone would be so kind to go through this and explain it to me it would be much appreciated.

I posted the assembler listing in its entirety not knowing what would be required to understand the question

                     1    **************************************************
                     2    *       BASIC SYSTEM "ONLINE" COMMAND            *
                     3    *                                                *
                     4    *              ONLINE [,Sn] [,Dn]                *
                     5    *                                                *
                     6    *          Copr. 1985 Gary B. Little             *
                     7    **************************************************
                     8    
            =003C    9    SBLOCK   EQU   $3C        ;Parameters for block move
            =003E    10   EBLOCK   EQU   $3E        
            =0042    11   FBLOCK   EQU   $42        
            =0073    12   HIMEM    EQU   $73        ;Use this as ONLINE buffer
                     13   
            =0200    14   IN       EQU   $200       ;Command input buffer
                     15   
            =BE06    16   EXTRNCMD EQU   $BE06      ;External command JMP instruction
            =BE09    17   ERROUT   EQU   $BE09      ;Error handler
            =BE50    18   XTRNADDR EQU   $BE50      ;Start of external cmd handler
            =BE52    19   XLEN     EQU   $BE52      ;External cmd name length (-1)
            =BE53    20   XCNUM    EQU   $BE53      ;Command # (0 for external)
            =BE54    21   PBITS    EQU   $BE54      ;Command parameter bits
            =BE56    22   FBITS    EQU   $BE56      ;Parameters found in parse
            =BE61    23   VSLOT    EQU   $BE61      ;Slot parameter specified
            =BE62    24   VDRIV    EQU   $BE62      ;Drive parameter specified
            =BEF5    25   GETBUFR  EQU   $BEF5      ;Get free space
                     26   
            =BF00    27   MLI      EQU   $BF00      ;Entry point to MLI
                     28   
            =FD8E    29   CROUT    EQU   $FD8E      ;Print a CR
            =FDED    30   COUT     EQU   $FDED      ;Standard character output subroutine
            =FE2C    31   MOVE     EQU   $FE2C      ;Block move subroutine
                     32   
                     34   
                     35            ORG   $2000      
                     36   
                     37   * Calculate # of pages that we need to reserve:
                     38   
002000: 38           39            SEC              
002001: A9 22        40            LDA   #>END      
002003: E9 21        41            SBC   #>CMDCODE  
002005: 8D 74 20     42            STA   PAGES      
002008: EE 74 20     43            INC   PAGES      
                     44   
00200B: AD 74 20     45            LDA   PAGES      ;Reserve the pages for the
00200E: 20 F5 BE     46            JSR   GETBUFR    : command handler
002011: 90 05 =2018  47            BCC   INSTALL    ;Clear carry if OK
                     48   
002013: A9 0E        49            LDA   #14        ;"PROGRAM TOO LARGE" error
002015: 4C 09 BE     50            JMP   ERROUT     
                     51   
002018: 8D 75 20     52   INSTALL  STA   PGSTART    ;Save the starting page
                     53   
                     54   * Install the command handler:
                     55   
00201B: AD 07 BE     56            LDA   EXTRNCMD+1 ;Set up link to
00201E: 8D 26 21     57            STA   NEXTCMD+1  ; existing external command.
002021: AD 08 BE     58            LDA   EXTRNCMD+2 
002024: 8D 27 21     59            STA   NEXTCMD+2  
                     60   
                     61   **************************************************
                     62   * Install the external command handler           *
                     63   * by storing its address after the               *
                     64   * JMP at EXTRNCMD                                *
                     65   **************************************************
                     66   
002027: A9 00        67            LDA   #0         
002029: 8D 07 BE     68            STA   EXTRNCMD+1 
00202C: AD 75 20     69            LDA   PGSTART    
00202F: 8D 08 BE     70            STA   EXTRNCMD+2 
                     71   
                     72   * Relocate the code
                     73   
002032: AD 75 20     74            LDA   PGSTART    ;Get new page #
002035: 8D 0F 21     75            STA   CMDCODE+$0F 
002038: 8D 1A 21     76            STA   CMDCODE+$1A 
00203B: 8D 32 21     77            STA   CMDCODE+$32 
00203E: 8D 49 21     78            STA   CMDCODE+$49 
002041: 8D 4E 21     79            STA   CMDCODE+$4E 
002044: 8D 55 21     80            STA   CMDCODE+$55 
002047: 8D 6F 21     81            STA   CMDCODE+$6F 
00204A: 8D 75 21     82            STA   CMDCODE+$75 
00204D: 8D 8A 21     83            STA   CMDCODE+$8A 
002050: 8D A4 21     84            STA   CMDCODE+$A4 
002053: 8D D5 21     85            STA   CMDCODE+$D5 
                     86   
                     87   * Set up parameters for block move to final location:
                     88   
002056: A9 00        89            LDA   #<CMDCODE  
002058: 85 3C        90            STA   SBLOCK     
00205A: A9 21        91            LDA   #>CMDCODE  
00205C: 85 3D        92            STA   SBLOCK+1   
                     93   
00205E: A9 03        94            LDA   #<END      
002060: 85 3E        95            STA   EBLOCK     
002062: A9 22        96            LDA   #>END      
002064: 85 3F        97            STA   EBLOCK+1   
                     98   
002066: A9 00        99            LDA   #0         
002068: 85 42        100           STA   FBLOCK     
00206A: AD 75 20     101           LDA   PGSTART    
00206D: 85 43        102           STA   FBLOCK+1   
                     103  
00206F: A0 00        104           LDY   #0         
002071: 4C 2C FE     105           JMP   MOVE       ;Move it!
                     106  
002074: 00           107  PAGES    DS    1          ;Length of command handler
002075: 00           108  PGSTART  DS    1          ;Starting page of command handler
                     109  
002076: 00 00 00 00  110           DS    $2100-*    ;(Must start on page boundary)
00207A: 00 00 00 00 00 00 00 00 
002082: 00 00 00 00 00 00 00 00 
00208A: 00 00 00 00 00 00 00 00 
002092: 00 00 00 00 00 00 00 00 
00209A: 00 00 00 00 00 00 00 00 
0020A2: 00 00 00 00 00 00 00 00 
0020AA: 00 00 00 00 00 00 00 00 
0020B2: 00 00 00 00 00 00 00 00 
0020BA: 00 00 00 00 00 00 00 00 
0020C2: 00 00 00 00 00 00 00 00 
0020CA: 00 00 00 00 00 00 00 00 
0020D2: 00 00 00 00 00 00 00 00 
0020DA: 00 00 00 00 00 00 00 00 
0020E2: 00 00 00 00 00 00 00 00 
0020EA: 00 00 00 00 00 00 00 00 
0020F2: 00 00 00 00 00 00 00 00 
0020FA: 00 00 00 00 00 00 
                     111  
            =2100    112  CMDCODE  EQU   *          
                     113  
                     114  **************************************************
                     115  * This is the command checker. It                *
                     116  * scans the input buffer to see                  *
                     117  * if the command has been entered                *
                     118  **************************************************
002100: D8           119           CLD              
002101: A0 00        120           LDY   #0         
002103: A2 00        121           LDX   #0         
002105: BD 00 02     122  CHKCMD   LDA   IN,X       ;Get command character
002108: E8           123           INX              
002109: C9 A0        124           CMP   #$A0       ;Is it a blank
00210B: F0 F8 =2105  125           BEQ   CHKCMD     ; If it is, ignore it
00210D: D9 EE 21     126           CMP   CMDNAME,Y  ;Same as our command?
002110: F0 0B =211D  127           BEQ   CHKCMD1    ;Yes, so branch
002112: C9 E0        128           CMP   #$E0       ;Lower case?
002114: 90 0E =2124  129           BCC   NOTFOUND   ;No, so branch
002116: 29 DF        130           AND   #$DF       ;Convert to uppercase
002118: D9 EE 21     131           CMP   CMDNAME,Y  ;OK now?
00211B: D0 07 =2124  132           BNE   NOTFOUND   ;No, so branch
00211D: C8           133  CHKCMD1  INY              
00211E: C0 06        134           CPY   #CMDLEN-CMDNAME ;At end?
002120: D0 E3 =2105  135           BNE   CHKCMD     ;No, so branch
002122: F0 04 =2128  136           BEQ   SETRULES   ;Yes, so branch
                     137  
002124: 38           138  NOTFOUND SEC              ;Set carry to indicate failure
002125: 4C 00 00     139  NEXTCMD  JMP   $0000      ;(Fill in when installed)
                     140  
002128: 88           141  SETRULES DEY              
002129: 8C 52 BE     142           STY   XLEN       ;Store command length - 1
                     143  
00212C: A9 51        144           LDA   #<EXECUTE  ;Put address of command handler
00212E: 8D 50 BE     145           STA   XTRNADDR   ; into XTRNADDR.
002131: A9 21        146           LDA   #>EXECUTE  
002133: 8D 51 BE     147           STA   XTRNADDR+1 
                     148  
002136: A9 00        149           LDA   #0         
002138: 8D 53 BE     150           STA   XCNUM      ;External cmd number = 0
                     151  
                     152  * Set up string parsing rules:
                     153  
00213B: A9 10        154           LDA   #$10       ;Pathname is optional
00213D: 8D 54 BE     155           STA   PBITS      
002140: A9 04        156           LDA   #$04       ;Slot and drive allowed
002142: 8D 55 BE     157           STA   PBITS+1    
                     158  
002145: A5 73        159           LDA   HIMEM      ;Set ON_LINE buffer (at least
002147: 8D EC 21     160           STA   BUFFER     ; 256 bytes) to free area
00214A: A5 74        161           LDA   HIMEM+1    ; beginning at HIMEM
00214C: 8D ED 21     162           STA   BUFFER+1   
                     163  
00214F: 18           164           CLC              ;Clear carry to indicate success
002150: 60           165           RTS              
                     166  
                     167  * BASIC.SYSTEM comes here after it has
                     168  * successfully parsed the command line:
                     169  
002151: A9 00        170  EXECUTE  LDA   #0         
002153: 8D EB 21     171           STA   UNITNUM    ;(Assume all volumes)
002156: AD 57 BE     172           LDA   FBITS+1    ;Examine result of parse
002159: 29 04        173           AND   #$04       ;Slot/drive specified?
00215B: F0 13 =2170  174           BEQ   DOCALL     ;No, so check everything
00215D: AD 61 BE     175           LDA   VSLOT      ;Get slot # specified
002160: 0A           176           ASL              
002161: 0A           177           ASL              
002162: 0A           178           ASL              
002163: 0A           179           ASL              ;Slot * 16
002164: AE 62 BE     180           LDX   VDRIV      ;Get drive # specified
002167: E0 02        181           CPX   #2         ;Drive 2?
002169: D0 02 =216D  182           BNE   SAVEUN     ;No, so branch
00216B: 09 80        183           ORA   #$80       ;Set "drive 2" bit
00216D: 8D EB 21     184  SAVEUN   STA   UNITNUM    ;Store slot/drive as unit num
                     185  
002170: 20 00 BF     186  DOCALL   JSR   MLI        
002173: C5           187           DFB   $C5        ;ONLINE call
002174: EA 21        188           DA    OLPARM     ;Address of parm table
                     189  
002176: 20 8E FD     190           JSR   CROUT      
002179: A0 00        191           LDY   #0         
00217B: 98           192  SCAN     TYA              
00217C: 48           193           PHA              
00217D: B1 73        194           LDA   (HIMEM),Y  ;Get slot/drive + length
00217F: F0 61 =21E2  195           BEQ   SCAN2      ;If $00 then all done
002181: 29 0F        196           AND   #$0F       ;Isolate length bits
002183: F0 4E =21D3  197           BEQ   NEXTNAME   ;If 0, then must be error
002185: 48           198           PHA              
                     199  
002186: A2 00        200           LDX   #0         
002188: BD F4 21     201  PRTMSG1  LDA   SLOTMSG,X  ;Print slot
00218B: F0 06 =2193  202           BEQ   PRTNUM1    
00218D: 20 ED FD     203           JSR   COUT       
002190: E8           204           INX              
002191: D0 F5 =2188  205           BNE   PRTMSG1    
                     206  
002193: B1 73        207  PRTNUM1  LDA   (HIMEM),Y  ;Get slot/drive + length
002195: 29 70        208           AND   #$70       ;Isolate slot bits
002197: 4A           209           LSR              
002198: 4A           210           LSR              
002199: 4A           211           LSR              
00219A: 4A           212           LSR              ;We now have slot #
00219B: 09 B0        213           ORA   #$B0       ;Convert to ASCCI digit
00219D: 20 ED FD     214           JSR   COUT       
                     215  
0021A0: A2 00        216           LDX   #0         
0021A2: BD FA 21     217  PRTMSG2  LDA   DRIVEMSG,X ;Print drive #
0021A5: F0 06 =21AD  218           BEQ   PRTNUM2    
0021A7: 20 ED FD     219           JSR   COUT       
0021AA: E8           220           INX              
0021AB: D0 F5 =21A2  221           BNE   PRTMSG2    
                     222  
0021AD: A2 B1        223  PRTNUM2  LDX   #$B1       ;Assume drive 1
0021AF: B1 73        224           LDA   (HIMEM),Y  
0021B1: 10 02 =21B5  225           BPL   PSKIP      ;Branch if drive 1
0021B3: A2 B2        226           LDX   #$B2       ;Must be drive 2
0021B5: 8A           227  PSKIP    TXA              
0021B6: 20 ED FD     228           JSR   COUT       
0021B9: A9 BA        229           LDA   #":        
0021BB: 20 ED FD     230           JSR   COUT       
0021BE: A9 A0        231           LDA   #$A0       
0021C0: 20 ED FD     232           JSR   COUT       
                     233  
0021C3: 68           234           PLA              
0021C4: AA           235           TAX              
0021C5: C8           236  PRTNAME  INY              
0021C6: B1 73        237           LDA   (HIMEM),Y  ;Get next character in name
0021C8: 09 80        238           ORA   #$80       ;Set high bit
0021CA: 20 ED FD     239           JSR   COUT       ; and display it
0021CD: CA           240           DEX              
0021CE: D0 F5 =21C5  241           BNE   PRTNAME    ;Branch until done
0021D0: 20 8E FD     242           JSR   CROUT      
                     243  
0021D3: AD EB 21     244  NEXTNAME LDA   UNITNUM    ;Was only one volume specified?
0021D6: D0 0A =21E2  245           BNE   SCAN2      ;Yes, so branch
                     246  
0021D8: 68           247           PLA              
0021D9: 18           248           CLC              
0021DA: 69 10        249           ADC   #16        ;Move to next name
0021DC: A8           250           TAY              
0021DD: C0 E0        251           CPY   #224       ;At end of table?
0021DF: D0 9A =217B  252           BNE   SCAN       ;No, so branch
0021E1: 48           253           PHA              
                     254  
0021E2: 68           255  SCAN2    PLA              
0021E3: 20 8E FD     256           JSR   CROUT      
0021E6: 18           257           CLC              ;CLC ++> no error
0021E7: A9 00        258           LDA   #0         ;Error code = 0
0021E9: 60           259           RTS              
                     260  
0021EA: 02           261  OLPARM   DFB   2          ;Two parameters
0021EB: 00           262  UNITNUM  DFB   0          ;Unit number (DSSS0000)
0021EC: 00 00        263  BUFFER   DA    $0000      ;Device buffer
                     264  
0021EE: CF CE CC C9  265  CMDNAME  ASC   "ONLINE"   ;Eternal command name
0021F2: CE C5 
            =21F4    266  CMDLEN   EQU   *          
                     267  
0021F4: D3 CC CF D4  268  SLOTMSG  ASC   "SLOT ",00 
0021F8: A0 00 
0021FA: AC A0 C4 D2  269  DRIVEMSG ASC   ", DRIVE ",00 
0021FE: C9 D6 C5 A0 00 
                     270  
            =2203    271  END      EQU   *          


End Merlin-16 assembly, 515 bytes, 0 errors, 271 lines, 48 symbols.

Elapsed time = 31 seconds.

Symbol table, alphabetical order:

   BUFFER  =$21EC      CHKCMD  =$2105      CHKCMD1 =$211D      CMDCODE =$2100
   CMDLEN  =$21F4      CMDNAME =$21EE      COUT    =$FDED      CROUT   =$FD8E
   DOCALL  =$2170      DRIVEMSG=$21FA      EBLOCK  =$3E        END     =$2203
   ERROUT  =$BE09      EXECUTE =$2151      EXTRNCMD=$BE06      FBITS   =$BE56
   FBLOCK  =$42        GETBUFR =$BEF5      HIMEM   =$73        IN      =$0200
   INSTALL =$2018      MLI     =$BF00      MOVE    =$FE2C      NEXTCMD =$2125
   NEXTNAME=$21D3      NOTFOUND=$2124      OLPARM  =$21EA      PAGES   =$2074
   PBITS   =$BE54      PGSTART =$2075      PRTMSG1 =$2188      PRTMSG2 =$21A2
   PRTNAME =$21C5      PRTNUM1 =$2193      PRTNUM2 =$21AD      PSKIP   =$21B5
   SAVEUN  =$216D      SBLOCK  =$3C        SCAN    =$217B      SCAN2   =$21E2
   SETRULES=$2128      SLOTMSG =$21F4      UNITNUM =$21EB      VDRIV   =$BE62
   VSLOT   =$BE61      XCNUM   =$BE53      XLEN    =$BE52      XTRNADDR=$BE50


Symbol table, numerical order:

   SBLOCK  =$3C        EBLOCK  =$3E        FBLOCK  =$42        HIMEM   =$73
   IN      =$0200      INSTALL =$2018      PAGES   =$2074      PGSTART =$2075
   CMDCODE =$2100      CHKCMD  =$2105      CHKCMD1 =$211D      NOTFOUND=$2124
   NEXTCMD =$2125      SETRULES=$2128      EXECUTE =$2151      SAVEUN  =$216D
   DOCALL  =$2170      SCAN    =$217B      PRTMSG1 =$2188      PRTNUM1 =$2193
   PRTMSG2 =$21A2      PRTNUM2 =$21AD      PSKIP   =$21B5      PRTNAME =$21C5
   NEXTNAME=$21D3      SCAN2   =$21E2      OLPARM  =$21EA      UNITNUM =$21EB
   BUFFER  =$21EC      CMDNAME =$21EE      CMDLEN  =$21F4      SLOTMSG =$21F4
   DRIVEMSG=$21FA      END     =$2203      EXTRNCMD=$BE06      ERROUT  =$BE09
   XTRNADDR=$BE50      XLEN    =$BE52      XCNUM   =$BE53      PBITS   =$BE54
   FBITS   =$BE56      VSLOT   =$BE61      VDRIV   =$BE62      GETBUFR =$BEF5
   MLI     =$BF00      CROUT   =$FD8E      COUT    =$FDED      MOVE    =$FE2C




4
  • Serious question: Did you try to read the code, like looking up what is at the location mentioned, e.g. CMDCODE+$0F, or read the program description on the page before?
    – Raffzahn
    Aug 17, 2022 at 19:47
  • 1
    Yes, I did, but I didn't quite understand. Now that it was explained to me I see it was quite simple. I guess I didn't see the forest for the trees.
    – mswade
    Aug 17, 2022 at 20:49
  • 1
    I'm sure we all know that feeling :))
    – Raffzahn
    Aug 17, 2022 at 21:20
  • FWIW, a more general way to relocate code is defined in PA #1: archive.org/details/programmers-aid-1/page/n27/mode/2up . It's a bit more complex than this approach.
    – fadden
    Aug 18, 2022 at 14:35

2 Answers 2

10

These are the page parts of all absolute addresses within the program. The whole process is described in detail on page 177 of the book (third paragraph).

The program is compiled to run at page $21 (see line 110). To make it run at any other page address (aka relocate it), all absolute references have to be adjusted to the new page. In this case the page (*1) is requested per GETBUFR in line 46, the value received saved in PGSTART (line 52) and then used to patch the program (strarting at line 74).

CMDCODE+$0F is for example the page part of the CMP CMDNAME,Y instruction in line 126, CMDCODE+$1A is the same operation in line 131, and so on.


*1 - Memory management under Prodos is done in pages of 256 bytes each.

1
  • 2
    I kept looking through the code for what was at $210F and so on. I guess I didn't understand what to find there
    – mswade
    Aug 17, 2022 at 20:53
9

The relocatable routine is assembled to $2100:

            =2100    112  CMDCODE  EQU   *

Relocation is simplified by the CMDCODE routine only occupying one page and starting at a page boundary, which makes the high byte of the relocation offset = zero.

The magic numbers you quoted are (low byte) offsets into the executable code of instruction arguments which self reference the original page, namely where the arguments use the page number $21. Here's the list of instructions where you can see the assembled bytes include $21:

00210D: D9 EE 21     126           CMP   CMDNAME,Y  ;Same as our command?
002118: D9 EE 21     131           CMP   CMDNAME,Y  ;OK now?
002131: A9 21        146           LDA   #>EXECUTE  
002147: 8D EC 21     160           STA   BUFFER     ; 256 bytes) to free area
00214C: 8D ED 21     162           STA   BUFFER+1   
002153: 8D EB 21     171           STA   UNITNUM    ;(Assume all volumes)
00216D: 8D EB 21     184  SAVEUN   STA   UNITNUM    ;Store slot/drive as unit num
002174: EA 21        188           DA    OLPARM     ;Address of parm table
002188: BD F4 21     201  PRTMSG1  LDA   SLOTMSG,X  ;Print slot
0021A2: BD FA 21     217  PRTMSG2  LDA   DRIVEMSG,X ;Print drive #
0021D3: AD EB 21     244  NEXTNAME LDA   UNITNUM    ;Was only one volume specified?

A clearer way to do this would be to add labels. (Note that some already have labels.)

00210D: D9 EE 21     126  RELOC1   CMP   CMDNAME,Y  ;Same as our command?
002118: D9 EE 21     131  RELOC2   CMP   CMDNAME,Y  ;OK now?
002131: A9 21        146  RELOC3   LDA   #>EXECUTE  
002147: 8D EC 21     160  RELOC4   STA   BUFFER     ; 256 bytes) to free area
00214C: 8D ED 21     162  RELOC5   STA   BUFFER+1   
002153: 8D EB 21     171  RELOC6   STA   UNITNUM    ;(Assume all volumes)
00216D: 8D EB 21     184  SAVEUN   STA   UNITNUM    ;Store slot/drive as unit num
002174: EA 21        188  RELOC8   DA    OLPARM     ;Address of parm table
002188: BD F4 21     201  PRTMSG1  LDA   SLOTMSG,X  ;Print slot
0021A2: BD FA 21     217  PRTMSG2  LDA   DRIVEMSG,X ;Print drive #
0021D3: AD EB 21     244  NEXTNAME LDA   UNITNUM    ;Was only one volume specified?

And then change the magic numbers as follows:

002035: 8D 0F 21     75            STA   RELOC1+2
002038: 8D 1A 21     76            STA   RELOC2+2
00203B: 8D 32 21     77            STA   RELOC3+1
00203E: 8D 49 21     78            STA   RELOC4+2
002041: 8D 4E 21     79            STA   RELOC5+2
002044: 8D 55 21     80            STA   RELOC6+2
002047: 8D 6F 21     81            STA   SAVEUN+2
00204A: 8D 75 21     82            STA   RELOC8+1
00204D: 8D 8A 21     83            STA   PRTMSG1+2
002050: 8D A4 21     84            STA   PRTMSG2+2
002053: 8D D5 21     85            STA   NEXTNAME+2

In that scheme, magic numbers are still required, because we need to account for argument lengths of 2 (for absolute) and 1 (for immediate).

Another way would be to label the statements following those instructions. For instance:

00210D: D9 EE 21     126           CMP   CMDNAME,Y  ;Same as our 
            =2110    127  RELOC1   EQU *

Then all the offset calculations would be -1.

002035: 8D 0F 21     75            STA   RELOC1-1
002038: 8D 1A 21     76            STA   RELOC2-1
00203B: 8D 32 21     77            STA   RELOC3-1
...
9
  • >00210D: D9 EE 21< and so the MSB is at $0F where we want to store PGSTART. Pretty simple now that its been explained to me. I looked for $210F and just looked at CMP CMDNAME,Y and didn't understand. Feeling pretty dense. Thank you and Raffzahn for your time to explain. I would mark booths correct but I don't think I can.
    – mswade
    Aug 17, 2022 at 21:07
  • How would the author know the magic numbers without the assembled listing?
    – mswade
    Aug 17, 2022 at 22:23
  • @mswade: They couldn't. They inspected the assembled listing (or the binary) and manually collated the magic numbers. That's why my suggested code above is better - less effort to change the code since it (mostly) calculates the magic numbers, but you still have to manage that list. Aug 17, 2022 at 22:49
  • 1
    @mswade: From page 177 that Raffzahn linked to: "Although it is possible to write a complex subroutine to patch the code automatically, we have chosen to patch it “manually” by inspecting the handler to identify addresses to be changed and then storing the new page number at these positions. If you change the handler in any way, you will have to re-determine which positions must be patched and make the necessary changes to the installation code." Aug 17, 2022 at 22:53
  • 1
    I didn't understand that reference "patch it "manually" by inspecting the handler" when I read it. That clears it up very much, thank you
    – mswade
    Aug 17, 2022 at 23:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .