-     OPT --syntax=abfw 
-     DEVICE  ZXSPECTRUM48, $5D00 
-   
-     ; prepare the code from address 0 to have table of offsets "from current address" 
-     ; (but store the resulting code from $8000) 
-     ORG     $8000 
-     DISP    $0000 
-     RELOCATE_START 
-   
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
- ;; relocator code, using address in BC as where the code did land 
- ;; ("RANDOMIZE USR xyz" will provide BC=xyz) 
- ;; the relocator will use the RELOCATE_TABLE data to adjust all instructions 
- ;; as needed for the actual address where the code was loaded 
- ;; (the relocator itself doesn't produce any relocation data) 
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-   
- relocator_code: 
- ; start of relocator 
-     ASSERT 0 < relocate_count   ; (for zero relocation_count the relocator is not needed!) 
-     ; BASIC sets BC to the address of start (after "RANDOMIZE USR x" BC=x upon entry) 
-         di 
-     ; preserve current SP into IX 
-         ld      ix,0 
-         add     ix,sp 
-     ; set SP to the relocation table data 
-         ld      hl,relocator_table-relocator_code   ; offset from start to the table 
-         add     hl,bc                               ; absolute address of table 
-         ld      sp,hl 
-     ; process the full table of relocation data (A + A' is counter of relocation values) 
-         ld      a,1+high relocate_count 
-         ex      af,af 
-         ld      a,1+low relocate_count 
-         jr      .relocate_loop_entry 
- .relocate_loop_outer: 
-         ex      af,af 
- .relocate_loop: 
-     ; relocate single record from the relocate table 
-         pop     hl 
-         add     hl,bc       ; HL = address of machine code to modify 
-         ld      e,(hl) 
-         inc     hl 
-         ld      d,(hl)      ; DE = value to modify 
-         ex      de,hl 
-         add     hl,bc       ; relocate the value 
-         ex      de,hl 
-         ld      (hl),d      ; patch the machine code in memory 
-         dec     hl 
-         ld      (hl),e 
- .relocate_loop_entry: 
-     ; loop until all "relocate_count" records were processed 
-         dec     a 
-         jr      nz,.relocate_loop 
-         ex      af,af 
-         dec     a 
-         jr      nz,.relocate_loop_outer 
-     ; restore SP 
-         ld      sp,ix 
- ; end of relocator 
-   
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
- ;; "user code" - some code which needs to be relocated after loading at some 
- ;; dynamic address (the relocation is done by code above, the following code 
- ;; is just small graphics effect using some hard-coded addresses which need 
- ;; relocation - as demonstration of the functionality) 
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-   
-     ; user code (will be relocated by relocator) 
- start: 
-     ; black border 
-         xor     a 
-         out     (254),a 
-     ; clear VRAM 
-         ld      hl,$4000 
-         ld      de,$4001 
-         ld      bc,$1800 
-         ld      (hl),l 
-         ldir 
-         ld      (hl),$40|4  ; bright green ink on black paper 
-         ld      bc,$300-1 
-         ldir 
-     ; print the graphics with "SjASMPlus" bitmap 
-         ld      hl,gfx_data 
-         ld      d,high $4800    ; $4800 address 
-         ld      a,8 
- draw_line 
-         ld      e,3*32 + 12 ; put it almost into middle of screen 
-         ld      bc,gfx_data.lineSz 
-         ldir 
-         inc     d 
-         dec     a 
-         jp      nz,draw_line 
-     ; keep the graphics scrolling around forever 
- scroll_loop: 
-         ei 
-         halt 
-         di 
-         ld      (.restore_sp),sp 
-         ld      sp,scroll_addresses 
-         ld      c,8 
- .one_line: 
-         pop     hl 
-         ld      a,(hl)      ; first byte value (to wrap around) 
-         pop     hl 
-         ld      b,gfx_data.lineSz 
-         rla 
- .one_line_loop: 
-         rl      (hl) 
-         dec     hl 
-         djnz    .one_line_loop 
-         dec     c 
-         jp      nz,.one_line 
- .restore_sp EQU $+1 
-         ld      sp,0 
-         jp      scroll_loop 
-   
- gfx_data: 
-     DG  -***--**----*-----***--*-----*-*****--**---------------- 
-     DG  **--*-**---***---**--*-**---**-**--**-**---------------- 
-     DG  **---------***---**----***-***-**--**-**-**--**--****--- 
-     DG  -***--**--**--*---***--**-*-**-*****--**-**--**-**------ 
-     DG  ---**--*--*****-----**-**-*-**-**-----**-**--**--***---- 
-     DG  *--**--*-**----*-*--**-**---**-**-----**-**--**----**--- 
-     DG  -***---*-**----*--***--**---**-**------**-*****-****---- 
-     DG  -----**------------------------------------------------- 
- .lineSz EQU     ($ - gfx_data)/8 
-   
- scroll_addresses: 
- vram_line_first_byte = $4800 + 3*32 + 12 
-     DUP     8 
-         DW  vram_line_first_byte                        ; first byte of line 
-         DW  vram_line_first_byte + gfx_data.lineSz - 1  ; last byte of line 
- vram_line_first_byte = vram_line_first_byte + $100 
-     EDUP 
-   
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
- ;; relocation data table is at the end of the code block 
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-   
- relocator_table: 
-     RELOCATE_TABLE 
-   
- ; total size of code block 
- code_size   EQU     $ - relocator_code 
-     RELOCATE_END 
-     ENT 
-   
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
- ;; BASIC loader for TAP file (in include file) 
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-   
-     INCLUDE "relocation_basic.i.asm" 
-   
-     MakeTape "relocate.tap", "relocate", $8000, code_size 
-   
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
- ;; ZX48 SNA file for debugging (enable by "IF 1" change) 
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
-   
-     IF 0    ; DEBUG use "1" to produce ZX48 snapshot file (simpler to debug in CSpect) 
-         SAVESNA "relocate.sna", $8000 
-     ENDIF 
-