home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
books
/
68k_book
/
arp_src
/
prg_4ap.s
< prev
next >
Wrap
Text File
|
1985-11-20
|
8KB
|
169 lines
; Program Name: PRG_4AP.S
; Assembly Instructions:
; Assemble in PC-relative mode and save with a TOS suffix.
; Program Function:
; This program simply establishes itself in memory as a Load and Stay
; Resident (LSR) program and prints its location to the video screen. The
; addresses printed are the program start address (not the basepage address)
; and the program end address.
; Program Purpose:
; To illustrate the role of GEMDOS function $31 in establishing a
; program as LSR.
; Execution Instructions:
; Execute the program from the desktop. When the addresses appear on
; the screen, write them down. Terminate execution by pressing the Return
; key. In the AssemPro debugger, go to the first address using the
; "from address" function. On the first line in the output field, you
; should see the second address (program_end) being loaded into register A3.
; Once this program has been executed, it will remain in ram memory until
; the computer is rebooted.
; WARNING: If this program or any other LSR program is executed from within
; the AssemPro debugger, upon exit from AssemPro, the operating
; system will not be able to clear the program from memory.
; Because the program will be residing in an area of memory that
; was controlled by AssemPro, the environment will be corrupted.
; You can confirm this by trying to reexecute AssemPro after you
; exit. You will receive a Bus error message.
; Furthermore, you will not be able to assemble a program until
; you reset the system.
; There is only one thing you can do if you execute a LSR program
; from within AssemPro; you must reset the system by turning it
; completely off, then back on. You can try a warm reset, but
; all bets are off if you do that.
program_start: ; Calculate program size and retain result.
lea program_end, a3 ; Fetch address of last memory location occupied
movea.l a3, a4 ; by the program. Copy into scratch register.
suba.l 4(a7), a3 ; Subtract basepage address from program end
; address. After this, the basepage address
; is no longer needed in this program.
fetch_stack_address:
lea stack, a7
print_memory_locations:
lea load_message, a0
bsr.s print_string
lea program_start, a0
move.l a0, d1 ; Transfer to D1 for binary to ASCII
; hexadecimal conversion.
; Note: Above, must load address into an address register first, then move
; to the data register for binary to hexadecimal conversion, in order to
; permit PC-relative assembly.
bsr.s bin_to_hex ; bin_to_hex expects binary number in D1.
lea hexadecimal, a0 ; Print the hexadecimal string.
bsr.s print_string
lea separator, a0 ; Print a separator between addresses.
bsr.s print_string
move.l a4, d1 ; Program end address is in scratch register.
bsr.s bin_to_hex
lea hexadecimal, a0
bsr.s print_string
bsr.s print_newline
wait_for_keypress: ; Give time to write down memory addresses.
move.w #8, -(sp) ; Function = c_necin = GEMDOS $8.
trap #1 ; GEMDOS call.
addq.l #2, sp
; Note: GEMDOS function $31 doesn't need the basepage address.
relinquish_processor_control: ; Maintain memory residency.
move.w #0, -(sp) ; See page 121 of Internals book.
move.l a3, -(sp) ; Program size.
move.w #$31, -(sp) ; Function = ptermres = GEMDOS $31.
trap #1
;
; SUBROUTINES
;
; The binary to ASCII hexadecimal conversion routine expects a number to be
; passed as a longword in register D1. Beginning with the most significant
; nibble (a nibble = four bits), each nibble is converted to its ASCII
; hexadecimal equivalent and stored in "hexadecimal", a null terminated
; buffer. Maximum size of the binary number is 32 bits = 8 nibbles.
; The algorithm discards leading zeroes.
; The conversion from binary nibble to hex digit is accomplished by
; extracting the character in the hex table that is located at the position
; defined by the decimal value of the nibble. For example, if the nibble
; is "1111", the decimal value is 15; the 15th element of the hex table is
; the letter F. The location in the table is specified by an offset from
; the address of the first character of the table, which is stored in A1.
; The value of the offset is stored in register D0. The addressing mode
; used to locate the appropriate table entry is "address register indirect
; with offset".
bin_to_hex: ; Expects binary number in D1.
lea hexadecimal, a0 ; A0 is pointer to array "hexadecimal".
tst.l d1 ; Test for contents = 0.
beq.s zero_passed ; Branch if number is 0.
lea hex_table, a1 ; A1 is pointer to array "hex_table".
lea hex_table, a1 ; A1 is pointer to array "hex_table".
moveq #7, d2 ; D2 is the loop counter for 8 nibbles.
discard_leading_zeroes:
rol.l #4, d1 ; Rotate most significant nibble to the
; least significant nibble position.
move.b d1, d0 ; Copy least significant byte of D1 to D0.
andi.b #$F, d0 ; Mask out most significant nibble of D0.
bne.s store_digit ; Branch and store if not leading zero.
dbra d2, discard_leading_zeroes
continue:
rol.l #4, d1 ; Rotate most significant nibble.
move.b d1, d0 ; Copy least significant byte of D1 to D0.
andi.b #$F, d0 ; Mask out most significant nibble of D0.
store_digit:
move.b 0(a1,d0.w), (a0)+ ; Store ASCII hexadecimal digit in buffer.
dbra d2, continue ; Continue looping until D2 = -1.
move.b #0, (a0) ; Terminate hexadecimal string with a null.
rts
zero_passed:
move.b #$30, (a0)+ ; Store an ASCII zero in "hexadecimal".
move.b #0, (a0) ; Terminate ASCII hexadecimal string with null.
lea hexadecimal, a0
rts
print_string: ; Expects address of string to be in A0.
pea (a0) ; Push address of string onto stack.
move.w #9, -(sp) ; Function = c_conws = GEMDOS $9.
trap #1 ; GEMDOS call
addq.l #6, sp ; Reset stack pointer to top of stack.
rts
print_newline: ; Prints a carriage return and linefeed.
pea newline ; Push address of string onto stack.
move.w #9, -(sp) ; Function = c_conws = GEMDOS $9.
trap #1 ; GEMDOS call
addq.l #6, sp
rts
data
hex_table: dc.b '0123456789ABCDEF'
newline: dc.b $D,$A,0
load_message: dc.b 'Installing PRG_4AP between hex addresses: ',0
separator: dc.b ' - ',0
align
bss
hexadecimal: ds.l 3 ; Output buffer. Must be NULL terminated.
ds.l 16
stack: ds.l 1
program_end: ds.l 0
end