home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / books / 68k_book / arp_src / prg_4ap.s < prev    next >
Text File  |  1985-11-20  |  8KB  |  169 lines

  1.  ; Program Name: PRG_4AP.S
  2.  
  3.  ; Assembly Instructions:
  4.  
  5.  ;    Assemble in PC-relative mode and save with a TOS suffix.
  6.  
  7.  ; Program Function:
  8.  
  9.  ;    This program simply establishes itself in memory as a Load and Stay
  10.  ; Resident (LSR) program and prints its location to the video screen.  The
  11.  ; addresses printed are the program start address (not the basepage address)
  12.  ; and the program end address.
  13.  
  14.  ; Program Purpose:
  15.  
  16.  ;    To illustrate the role of GEMDOS function $31 in establishing a
  17.  ; program as LSR.
  18.  
  19.  ; Execution Instructions:
  20.  
  21.  ;    Execute the program from the desktop.  When the addresses appear on
  22.  ; the screen, write them down.  Terminate execution by pressing the Return
  23.  ; key.  In the AssemPro debugger, go to the first address using the
  24.  ; "from address" function.  On the first line in the output field, you
  25.  ; should see the second address (program_end) being loaded into register A3.
  26.  
  27.  ;    Once this program has been executed, it will remain in ram memory until
  28.  ; the computer is rebooted.
  29.  
  30.  ; WARNING: If this program or any other LSR program is executed from within
  31.  ;          the AssemPro debugger, upon exit from AssemPro, the operating
  32.  ;          system will not be able to clear the program from memory.
  33.  
  34.  ;          Because the program will be residing in an area of memory that
  35.  ;          was controlled by AssemPro, the environment will be corrupted.
  36.  ;          You can confirm this by trying to reexecute AssemPro after you
  37.  ;          exit.  You will receive a Bus error message.
  38.  
  39.  ;          Furthermore, you will not be able to assemble a program until
  40.  ;          you reset the system.
  41.  
  42.  ;          There is only one thing you can do if you execute a LSR program
  43.  ;          from within AssemPro; you must reset the system by turning it
  44.  ;          completely off, then back on.  You can try a warm reset, but
  45.  ;          all bets are off if you do that. 
  46.  
  47. program_start:                  ; Calculate program size and retain result.
  48.  lea        program_end, a3     ; Fetch address of last memory location occupied
  49.  movea.l    a3, a4              ; by the program.  Copy into scratch register.
  50.  suba.l     4(a7), a3           ; Subtract basepage address from program end 
  51.                                 ; address.  After this, the basepage address
  52.                                 ; is no longer needed in this program.
  53. fetch_stack_address:
  54.  lea        stack, a7
  55.  
  56. print_memory_locations:   
  57.  lea        load_message, a0
  58.  bsr.s      print_string
  59.  lea        program_start, a0
  60.  move.l     a0, d1              ; Transfer to D1 for binary to ASCII
  61.                                 ; hexadecimal conversion.
  62.  
  63.  ; Note: Above, must load address into an address register first, then move
  64.  ; to the data register for binary to hexadecimal conversion, in order to
  65.  ; permit PC-relative assembly.
  66.  
  67.  bsr.s      bin_to_hex          ; bin_to_hex expects binary number in D1.
  68.  lea        hexadecimal, a0     ; Print the hexadecimal string.
  69.  bsr.s      print_string
  70.  lea        separator, a0       ; Print a separator between addresses.
  71.  bsr.s      print_string
  72.  move.l     a4, d1              ; Program end address is in scratch register.          
  73.  bsr.s      bin_to_hex      
  74.  lea        hexadecimal, a0
  75.  bsr.s      print_string
  76.  bsr.s      print_newline
  77.  
  78. wait_for_keypress:              ; Give time to write down memory addresses.
  79.  move.w     #8, -(sp)           ; Function = c_necin = GEMDOS $8.
  80.  trap       #1                  ; GEMDOS call.
  81.  addq.l     #2, sp
  82.  
  83.  ; Note: GEMDOS function $31 doesn't need the basepage address.
  84.  
  85. relinquish_processor_control:   ; Maintain memory residency.
  86.  move.w    #0, -(sp)            ; See page 121 of Internals book.
  87.  move.l    a3, -(sp)            ; Program size.
  88.  move.w    #$31, -(sp)          ; Function = ptermres = GEMDOS $31.
  89.  trap      #1
  90.  
  91.  ; 
  92.  ; SUBROUTINES
  93.  ;
  94.  
  95.  ; The binary to ASCII hexadecimal conversion routine expects a number to be
  96.  ; passed as a longword in register D1.  Beginning with the most significant
  97.  ; nibble (a nibble = four bits), each nibble is converted to its ASCII
  98.  ; hexadecimal equivalent and stored in "hexadecimal", a null terminated
  99.  ; buffer.  Maximum size of the binary number is 32 bits = 8 nibbles.
  100.  
  101.  ; The algorithm discards leading zeroes.
  102.  
  103.  ; The conversion from binary nibble to hex digit is accomplished by 
  104.  ; extracting the character in the hex table that is located at the position
  105.  ; defined by the decimal value of the nibble.  For example, if the nibble
  106.  ; is "1111", the decimal value is 15; the 15th element of the hex table is
  107.  ; the letter F.  The location in the table is specified by an offset from
  108.  ; the address of the first character of the table, which is stored in A1.
  109.  ; The value of the offset is stored in register D0.  The addressing mode
  110.  ; used to locate the appropriate table entry is "address register indirect
  111.  ; with offset".  
  112.  
  113. bin_to_hex:                      ; Expects binary number in D1.   
  114.  lea        hexadecimal, a0      ; A0 is pointer to array "hexadecimal".
  115.  tst.l      d1                   ; Test for contents = 0.
  116.  beq.s      zero_passed          ; Branch if number is 0.
  117.  lea        hex_table, a1        ; A1 is pointer to array "hex_table".
  118.  lea        hex_table, a1        ; A1 is pointer to array "hex_table".
  119.  moveq      #7, d2               ; D2 is the loop counter for 8 nibbles.
  120.  
  121. discard_leading_zeroes: 
  122.  rol.l      #4, d1               ; Rotate most significant nibble to the
  123.                                  ; least significant nibble position.
  124.  move.b     d1, d0               ; Copy least significant byte of D1 to D0.
  125.  andi.b     #$F, d0              ; Mask out most significant nibble of D0.
  126.  bne.s      store_digit          ; Branch and store if not leading zero.
  127.  dbra       d2, discard_leading_zeroes
  128. continue:
  129.  rol.l      #4, d1               ; Rotate most significant nibble.
  130.  move.b     d1, d0               ; Copy least significant byte of D1 to D0.
  131.  andi.b     #$F, d0              ; Mask out most significant nibble of D0.
  132. store_digit:
  133.  move.b     0(a1,d0.w), (a0)+    ; Store ASCII hexadecimal digit in buffer.
  134.  dbra       d2, continue         ; Continue looping until D2 = -1.
  135.  move.b     #0, (a0)             ; Terminate hexadecimal string with a null.
  136.  rts
  137. zero_passed:
  138.  move.b     #$30, (a0)+         ; Store an ASCII zero in "hexadecimal".
  139.  move.b     #0, (a0)            ; Terminate ASCII hexadecimal string with null.
  140.  lea        hexadecimal, a0
  141.  rts
  142.  
  143. print_string:                   ; Expects address of string to be in A0.
  144.  pea        (a0)                ; Push address of string onto stack.
  145.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  146.  trap       #1                  ; GEMDOS call
  147.  addq.l     #6, sp              ; Reset stack pointer to top of stack.
  148.  rts
  149.  
  150. print_newline:                  ; Prints a carriage return and linefeed.
  151.  pea        newline             ; Push address of string onto stack.
  152.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  153.  trap       #1                  ; GEMDOS call
  154.  addq.l     #6, sp
  155.  rts
  156.  
  157.  data
  158. hex_table:       dc.b  '0123456789ABCDEF'
  159. newline:         dc.b  $D,$A,0
  160. load_message:    dc.b  'Installing PRG_4AP between hex addresses: ',0
  161. separator:       dc.b  ' - ',0
  162.  align
  163.  bss
  164. hexadecimal:     ds.l  3   ; Output buffer.  Must be NULL terminated.
  165.                  ds.l 16
  166. stack:           ds.l  1
  167. program_end:     ds.l  0
  168.  end