mirror of
https://github.com/gwenhael-le-moine/x48.git
synced 2024-11-16 19:50:21 +01:00
465 lines
7.1 KiB
ArmAsm
465 lines
7.1 KiB
ArmAsm
|
;
|
||
|
; $Id: ROMDump.s,v 1.4 1995/01/11 18:21:36 ecd Exp ecd $
|
||
|
;
|
||
|
; This file is part of ROMDump, a ROM dump utility for the HP48 Calculator.
|
||
|
; Copyright (C) 1994 Eddie C. Dost (ecd@dressler.de)
|
||
|
;
|
||
|
; This program is free software; you can redistribute it and/or modify
|
||
|
; it under the terms of the GNU General Public License as published by
|
||
|
; the Free Software Foundation; either version 2 of the License, or
|
||
|
; (at your option) any later version.
|
||
|
;
|
||
|
; This program is distributed in the hope that it will be useful,
|
||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
; GNU General Public License for more details.
|
||
|
;
|
||
|
; You should have received a copy of the GNU General Public License
|
||
|
; along with this program; if not, write to the Free Software
|
||
|
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
|
;
|
||
|
; Usage:
|
||
|
;
|
||
|
; (2: hxs, 1: hxs --> ) pop start address from level 2,
|
||
|
; pop end address from level 1, and dump
|
||
|
; ROM to the serial at 9600 baud using
|
||
|
; lines of form "aaaaa:hhhhhhhhhhhhhhhh\n\r"
|
||
|
; with 16 nibbles ROM data hhhhhhhhhhhhhhhh
|
||
|
; at address aaaaa.
|
||
|
;
|
||
|
; machine independent addresses (supported by HP)
|
||
|
;
|
||
|
AllowIntr equ $010e5
|
||
|
DisableIntr equ $01115
|
||
|
DOBINT equ $02911
|
||
|
DOCOL equ $02d9d
|
||
|
DOCODE equ $02dcc
|
||
|
SEMI equ $0312b
|
||
|
GETPTRLOOP equ $05143
|
||
|
SAVPTR equ $0679b
|
||
|
GETPTR equ $067d2
|
||
|
CK2NOLASTWD equ $18a8d
|
||
|
CKandDISPATCH1 equ $18fb2
|
||
|
VERSTRING equ $30794
|
||
|
PopASavptr equ $3251c
|
||
|
;
|
||
|
; machine independent addresses (NOT supported by HP)
|
||
|
;
|
||
|
POPHXS equ $53f8d
|
||
|
|
||
|
;
|
||
|
; machine dependent addresses
|
||
|
;
|
||
|
sx_GosubHidC equ $026bf
|
||
|
sx_prog_low equ $700f1 ; IRAMBUFF
|
||
|
sx_prog_high equ $f00f1 ; IRAMBUFF when RAM configured high
|
||
|
|
||
|
gx_GosubHidC equ $026ca
|
||
|
gx_prog_low equ $800f5 ; IRAMBUFF
|
||
|
gx_prog_high equ $c00f5 ; IRAMBUFF when RAM configured high
|
||
|
gx_LINECOUNT equ $8069a
|
||
|
|
||
|
;
|
||
|
; flags used
|
||
|
;
|
||
|
sGX equ 0
|
||
|
sHIGH equ 1
|
||
|
|
||
|
;
|
||
|
; begin off assembler code
|
||
|
;
|
||
|
textr "HPHP48-R"
|
||
|
|
||
|
dcr.5 DOCOL
|
||
|
dcr.5 CK2NOLASTWD
|
||
|
dcr.5 CKandDISPATCH1
|
||
|
dcr.5 DOBINT
|
||
|
dcr.5 $000bb
|
||
|
|
||
|
;
|
||
|
; only executed when (2: hxs, 1: hxs)
|
||
|
;
|
||
|
dcr.5 DOCOL
|
||
|
dcr.5 VERSTRING
|
||
|
|
||
|
dcr.5 DOCODE
|
||
|
code_start
|
||
|
dcr.5 code_end-code_start
|
||
|
|
||
|
jsr DisableIntr
|
||
|
|
||
|
;
|
||
|
; figure out version
|
||
|
;
|
||
|
jsr PopASavptr
|
||
|
move.1 #0, p
|
||
|
move.5 #24, c.p
|
||
|
add.a c, a
|
||
|
move.a a, d1
|
||
|
move.b (d1), a
|
||
|
move.2 #$4a, c.p ; 'J' == last version for S/SX
|
||
|
bclr #sGX, st
|
||
|
ble.b a, c, got_version
|
||
|
bset #sGX, st
|
||
|
got_version
|
||
|
bclr #sHIGH, st
|
||
|
|
||
|
;
|
||
|
; get arguments
|
||
|
;
|
||
|
jsr GETPTR
|
||
|
jsr POPHXS
|
||
|
move.1 #0, p
|
||
|
move.5 #$ffff0, c.p
|
||
|
and.a c, a
|
||
|
move.a a, r4
|
||
|
|
||
|
jsr GETPTR
|
||
|
jsr POPHXS
|
||
|
move.1 #0, p
|
||
|
move.5 #$ffff0, c.p
|
||
|
and.a c, a
|
||
|
move.a a, r3
|
||
|
|
||
|
;
|
||
|
; open IO
|
||
|
;
|
||
|
move.5 #$00110, d1
|
||
|
move.1 #8, a.p
|
||
|
move.1 a, (d1)
|
||
|
|
||
|
;
|
||
|
; set speed to 9600 baud
|
||
|
;
|
||
|
move.2 #$0d, d1
|
||
|
move.1 #6, a.p
|
||
|
move.1 a, (d1)
|
||
|
|
||
|
;
|
||
|
; dump ROM $00000 - $6ffff
|
||
|
;
|
||
|
dump_rom_0
|
||
|
move.a r3, a
|
||
|
move.5 #$6fff0, c.p
|
||
|
bgt.a a, c, dump_rom_7
|
||
|
move.a a, r1
|
||
|
|
||
|
move.a r4, c
|
||
|
move.a c, b
|
||
|
move.5 #$6fff0, c.p
|
||
|
ble.a b, c, end_addr_0
|
||
|
move.a c, b
|
||
|
end_addr_0
|
||
|
subr.a b, a
|
||
|
bcc continue_0
|
||
|
bra.3 dump_done
|
||
|
continue_0
|
||
|
move.a a, r2
|
||
|
|
||
|
bsr.3 prog_start
|
||
|
|
||
|
move.5 #$70000, a.p
|
||
|
move.a a, r3
|
||
|
|
||
|
;
|
||
|
; dump ROM $70000 - $7ffff
|
||
|
;
|
||
|
dump_rom_7
|
||
|
move.a r3, a
|
||
|
move.5 #$7fff0, c.p
|
||
|
bgt.a a, c, dump_done_7
|
||
|
bra.3 continue_7
|
||
|
dump_done_7
|
||
|
bbs #sGX, st, continue_8
|
||
|
bra.3 dump_done
|
||
|
continue_8
|
||
|
bra.3 dump_rom_8
|
||
|
continue_7
|
||
|
move.a a, r1
|
||
|
|
||
|
move.a r4, c
|
||
|
move.a c, b
|
||
|
move.5 #$7fff0, c.p
|
||
|
ble.a b, c, end_addr_7
|
||
|
move.a c, b
|
||
|
end_addr_7
|
||
|
subr.a b, a
|
||
|
bcc continue_7_2
|
||
|
bra.3 dump_done
|
||
|
continue_7_2
|
||
|
move.a a, r2
|
||
|
|
||
|
bbs #sGX, st, gx_dump_rom_7
|
||
|
bsr.3 copy_prog
|
||
|
move.5 #sx_prog_high, c.p
|
||
|
jsr sx_GosubHidC
|
||
|
bsr.3 copy_prog
|
||
|
bra.3 dump_done
|
||
|
|
||
|
gx_dump_rom_7
|
||
|
;
|
||
|
; unconfigure devices at 7e000 - 7ffff
|
||
|
;
|
||
|
move.5 #$7f000, c.p
|
||
|
uncnfg
|
||
|
move.5 #$7e000, c.p
|
||
|
uncnfg
|
||
|
|
||
|
bsr.3 prog_start
|
||
|
|
||
|
;
|
||
|
; reconfigure devices at 7e000 - 7ffff
|
||
|
;
|
||
|
move.5 #$ff000, c.p
|
||
|
config
|
||
|
move.5 #$7f000, c.p
|
||
|
config
|
||
|
move.5 #$ff000, c.p
|
||
|
config
|
||
|
move.5 #$7e000, c.p
|
||
|
config
|
||
|
|
||
|
move.5 #$80000, a.p
|
||
|
move.a a, r3
|
||
|
|
||
|
;
|
||
|
; dump ROM $80000 - $bffff
|
||
|
;
|
||
|
dump_rom_8
|
||
|
move.a r3, a
|
||
|
move.5 #$bfff0, c.p
|
||
|
bgt.a a, c, dump_rom_c
|
||
|
move.a a, r1
|
||
|
|
||
|
move.a r4, c
|
||
|
move.a c, b
|
||
|
move.5 #$bfff0, c.p
|
||
|
ble.a b, c, end_addr_8
|
||
|
move.a c, b
|
||
|
end_addr_8
|
||
|
subr.a b, a
|
||
|
bcc continue_8_2
|
||
|
bra.3 dump_done
|
||
|
continue_8_2
|
||
|
move.a a, r2
|
||
|
|
||
|
bsr.3 copy_prog
|
||
|
move.5 #gx_prog_high, c.p
|
||
|
jsr gx_GosubHidC
|
||
|
bsr.3 copy_prog
|
||
|
|
||
|
move.5 #$c0000, a.p
|
||
|
move.a a, r3
|
||
|
|
||
|
;
|
||
|
; dump ROM $c0000 - $fffff
|
||
|
;
|
||
|
dump_rom_c
|
||
|
move.a r3, a
|
||
|
move.a a, r1
|
||
|
|
||
|
move.a r4, c
|
||
|
move.a c, b
|
||
|
move.5 #$ffff0, c.p
|
||
|
ble.a b, c, end_addr_c
|
||
|
move.a c, b
|
||
|
end_addr_c
|
||
|
subr.a b, a
|
||
|
bcs dump_done
|
||
|
move.a a, r2
|
||
|
|
||
|
bsr.3 copy_prog
|
||
|
bset #sHIGH, st
|
||
|
jsr gx_prog_low
|
||
|
bsr.3 copy_prog
|
||
|
|
||
|
dump_done
|
||
|
;
|
||
|
; close IO
|
||
|
;
|
||
|
bsr.3 send_crnl
|
||
|
move.5 #$00110, d1
|
||
|
move.1 #0, a.p
|
||
|
move.1 a, (d1)
|
||
|
|
||
|
;
|
||
|
; back to RPL
|
||
|
;
|
||
|
jsr AllowIntr
|
||
|
jmp GETPTRLOOP
|
||
|
|
||
|
;
|
||
|
; exchange program with memory at address prog_low
|
||
|
;
|
||
|
copy_prog
|
||
|
move.a pc, c
|
||
|
prog_offset
|
||
|
move.5 #prog_start-prog_offset, a.p
|
||
|
add.a a, c
|
||
|
move.a c, d0
|
||
|
bbs #sGX, st, gx_addr
|
||
|
move.5 #sx_prog_low, d1
|
||
|
bra.3 sx_addr
|
||
|
gx_addr
|
||
|
move.5 #gx_prog_low, d1
|
||
|
sx_addr
|
||
|
move.5 #prog_end-prog_start, a.p
|
||
|
lsr.a #4, a
|
||
|
move.a a, b
|
||
|
|
||
|
copy_word
|
||
|
move.w (d0), a
|
||
|
move.w (d1), c
|
||
|
move.w c, (d0)
|
||
|
move.w a, (d1)
|
||
|
add.a #16, d0
|
||
|
add.a #16, d1
|
||
|
dec.a b
|
||
|
bcc copy_word
|
||
|
rtn
|
||
|
|
||
|
;
|
||
|
; this is the start of the actual dump routine
|
||
|
;
|
||
|
prog_start
|
||
|
bbc #sHIGH, st, skip_uncover_c
|
||
|
;
|
||
|
; uncover ROM at c0000 - fffff
|
||
|
;
|
||
|
move.5 #$7f000, d0
|
||
|
move.b (d0), c
|
||
|
move.5 #gx_LINECOUNT, d0
|
||
|
move.b (d0), c
|
||
|
bset #7, c
|
||
|
move.b c, (d0)
|
||
|
move.5 #$00128, d0
|
||
|
move.b c, (d0)
|
||
|
move.5 #$c0000, c.p
|
||
|
uncnfg
|
||
|
uncnfg
|
||
|
|
||
|
skip_uncover_c
|
||
|
;
|
||
|
; get start address and number of words
|
||
|
;
|
||
|
move.a r1, a
|
||
|
move.a a, d0
|
||
|
move.a r2, a
|
||
|
|
||
|
;
|
||
|
; dump the ROM
|
||
|
;
|
||
|
loop
|
||
|
move.a a, r0
|
||
|
bsr.3 send_addr
|
||
|
move.2 #$3a, c.p
|
||
|
bsr.3 send_char
|
||
|
move.w (d0), c
|
||
|
bsr.3 send_data
|
||
|
bsr.3 send_crnl
|
||
|
|
||
|
add.a #16, d0
|
||
|
move.a r0, a
|
||
|
sub.a #16, a
|
||
|
bcc loop
|
||
|
|
||
|
bbc #sHIGH, st, skip_cover_c
|
||
|
;
|
||
|
; reconfigure memory ports at c0000
|
||
|
;
|
||
|
move.5 #$c0000, c.p
|
||
|
config
|
||
|
config
|
||
|
config
|
||
|
config
|
||
|
move.5 #gx_LINECOUNT, d0
|
||
|
move.b (d0), c
|
||
|
bclr #7, c
|
||
|
move.b c, (d0)
|
||
|
move.5 #$00128, d0
|
||
|
move.b c, (d0)
|
||
|
move.5 #$7f040, d0
|
||
|
move.b (d0), c
|
||
|
|
||
|
skip_cover_c
|
||
|
rtn
|
||
|
|
||
|
;
|
||
|
; send data in C.W as hex characters
|
||
|
;
|
||
|
send_data
|
||
|
move.w c, b
|
||
|
move.2 #$0f, c.p
|
||
|
move.b c, d
|
||
|
bra.3 send_all
|
||
|
|
||
|
;
|
||
|
; send addr in D0 as hex characters
|
||
|
;
|
||
|
send_addr
|
||
|
exg.a a, d0
|
||
|
move.a a, c
|
||
|
exg.a a, d0
|
||
|
exg.1 p, c.4
|
||
|
exg.1 p, c.0
|
||
|
exg.1 p, c.4
|
||
|
exg.1 p, c.3
|
||
|
exg.1 p, c.1
|
||
|
exg.1 p, c.3
|
||
|
move.a c, b
|
||
|
move.2 #$04, c.p
|
||
|
move.b c, d
|
||
|
|
||
|
;
|
||
|
; send D.B many nibbles from B.W
|
||
|
;
|
||
|
send_all
|
||
|
clr.b c
|
||
|
move.p b, c
|
||
|
bsr.3 send_hex_nib
|
||
|
lsr.w #4, b
|
||
|
dec.b d
|
||
|
bcc send_all
|
||
|
rtn
|
||
|
|
||
|
;
|
||
|
; send "\n\r"
|
||
|
;
|
||
|
send_crnl
|
||
|
move.2 #$0d, c.p
|
||
|
bsr.3 send_char
|
||
|
move.2 #$0a, c.p
|
||
|
bsr.3 send_char
|
||
|
rtn
|
||
|
|
||
|
;
|
||
|
; send nibble in C.B as hex character
|
||
|
;
|
||
|
send_hex_nib
|
||
|
move.2 #$30, a.p
|
||
|
add.b a, c
|
||
|
move.2 #$39, a.p
|
||
|
ble.b c, a, send_char
|
||
|
move.2 #$07, a.p
|
||
|
add.b a, c
|
||
|
;
|
||
|
; send character in C.B
|
||
|
;
|
||
|
send_char
|
||
|
move.5 #$00112, d1
|
||
|
xmtrdy
|
||
|
move.1 (d1), a
|
||
|
bbs #0, a, xmtrdy
|
||
|
move.2 #$16, d1
|
||
|
move.b c, (d1)
|
||
|
rtn
|
||
|
|
||
|
prog_end
|
||
|
dcr.8 $00000000
|
||
|
dcr.8 $00000000
|
||
|
|
||
|
code_end
|
||
|
|
||
|
dcr.5 SEMI ; end of DISPATCH
|
||
|
dcr.5 SEMI ; end of program object
|