Disassembling the CP/M boot loader
Posted: Sun Feb 02, 2020 8:53 am
I have disassembled the CP/M boot loader so that it is now fully compilable and also modifiable. I have added notes to the source code that is shown below and is also attached to this post. This has been disassembled in the past and is in the Archive (http://adamarchive.org/archive/Adam/Tec ... 20Adam.pdf but that disassembly is not compilable or modifiable.
Code: Select all
; **************************************************************
;
; Coleco Adam CP/M 2.2 BOOT disassembly
;
; William "Milli" Hicks
;
; 01/29/2020 Start disassembly
; 01/30/2020 Initial disassembly complete
;
; **************************************************************
; **************************************************************
;
; Memory storage locations
;
; **************************************************************
RAMDISK .equ 04dh ; RAMDISK FFh = No
BOOTDEVICE .equ 04eh ; EOS device number booted from
CPMBOOT .equ 04fh ; 0,1 Tape 1,2. 2,3 Disk 1,2
MEMLOC1 .equ 0ee3bh
; **************************************************************
;
; IO Ports
;
; **************************************************************
MEMBANK .equ 07fh
.org 0c800h ; Initial load point
jr L_C803 ; c800 18 01
push hl ; c802 e5
L_C803:
; **************************************************************
;
; Put a RET at the NMI address of 66h to disable any NMI's
; that are happening.
;
; Not sure why they didn't use RETI (RETurn Interrupt) except
; that the RET instruction uses 1 cycle and the RETI uses 4.
;
; **************************************************************
ld a,$c9 ; c803 3e c9
ld ($0066),a ; c805 32 66 00
; **************************************************************
;
; Set the stack to start building down from the loaded code
;
; **************************************************************
ld sp,$c7ff ; c808 31 ff c7
; **************************************************************
;
; NULL A then test which device we booted from.
;
; When done A will hold the drive we booted from:
;
; 0 = Tape 1
; 1 = Tape 2
; 2 = Disk 1
; 3 = Disk 2
;
; The boot device is held in register B. If bit 3 is set then the
; boot device is 8 or 18h (tape 1 or 2).
;
; **************************************************************
xor a ; c80b af
bit 3,b ; c80c cb 58
; **************************************************************
;
; Jump if bit 3 is set so its tape 1 or 2
;
; **************************************************************
jr nz,L_C819 ; c80e 20 09
; **************************************************************
;
; Setup for disk 1 and test if its disk 2
;
; **************************************************************
ld a,$02 ; c810 3e 02
bit 0,b ; c812 cb 40
; **************************************************************
;
; Bit 0 not set so its disk 1
;
; **************************************************************
jr z,L_C81D ; c814 28 07
; **************************************************************
;
; Bit set so its tape 2 or disk 2
;
; **************************************************************
L_C816:
inc a ; c816 3c
jr L_C81D ; c817 18 04
L_C819:
; **************************************************************
;
; Bit 4 set if we are booting from tape 2
;
; **************************************************************
bit 4,b ; c819 cb 60
jr nz,L_C816 ; c81b 20 f9
L_C81D:
; **************************************************************
;
; Save the boot number (0 - 3) and default to no RAM disk
;
; **************************************************************
ld (CPMBOOT),a ; c81d 32 4f 00
ld a,$ff ; c820 3e ff
ld (RAMDISK),a ; c822 32 4d 00
; **************************************************************
;
; Save the EOS boot device number (4,5,8,18h)
;
; **************************************************************
ld a,b ; c825 78
ld (BOOTDEVICE),a ; c826 32 4e 00
; **************************************************************
;
; Setup to load BIOS from tracks 1 to 7 (6kb) to memory
; address 0da00h. This only loads one block at at time
;
; **************************************************************
ld h,$06 ; c829 26 06
ld bc,$0001 ; c82b 01 01 00
ld de,$da00 ; c82e 11 00 da
L_C831:
push hl ; c831 e5
push af ; c832 f5
push bc ; c833 c5
push de ; c834 d5
; **************************************************************
;
; Load the tracks
;
; **************************************************************
call L_C955 ; c835 cd 55 c9
; **************************************************************
;
; Jump if carry clear = Error loading BIOS
;
; **************************************************************
jr nc,L_C89A ; c838 30 60
; **************************************************************
;
; Track loaded
;
; **************************************************************
pop de ; c83a d1
ld hl,$0400 ; c83b 21 00 04
add hl,de ; c83e 19
ex de,hl ; c83f eb
pop bc ; c840 c1
inc bc ; c841 03
pop af ; c842 f1
pop hl ; c843 e1
dec h ; c844 25
; **************************************************************
;
; Do more tracks until H = 0 (6 tracks total)
;
; **************************************************************
jr nz,L_C831 ; c845 20 ea
; **************************************************************
;
; Check for expansion RAM and if so set up the drive M: ram disk
;
; Setup to check lower 32K of expansion ram. Only tests the first
; 5K of data and assumes that the rest of the expansion RAM is ok
; if this passes.
;
; It tests the following bytes in low expansion ram:
;
; 132, 1156, 2180, 3204 and 4228
;
; **************************************************************
ld a,$02 ; c847 3e 02
out (MEMBANK),a ; c849 d3 7f
ld hl,$0084 ; c84b 21 84 00
ld de,$0400 ; c84e 11 00 04
ld b,$05 ; c851 06 05
L_C853:
; **************************************************************
;
; Text if expansion RAM exists by writing and reading from it
;
; **************************************************************
ld a,(hl) ; c853 7e
ld c,a ; c854 4f
xor $55 ; c855 ee 55
ld (hl),a ; c857 77
cp (hl) ; c858 be
; **************************************************************
;
; No expansion RAM so jump
;
; **************************************************************
jr nz,L_C88D ; c859 20 32
xor $55 ; c85b ee 55
ld (hl),c ; c85d 71
cp (hl) ; c85e be
; **************************************************************
;
; No expansion RAM so jump
;
; **************************************************************
jr nz,L_C88D ; c85f 20 2c
; **************************************************************
;
; Next 1kb boundary - do till B = 0
;
; **************************************************************
add hl,de ; c861 19
djnz L_C853 ; c862 10 ef
ld bc,$14e9 ; c864 01 e9 14
ld hl,($0082) ; c867 2a 82 00
sbc hl,bc ; c86a ed 42
jr z,L_C87B ; c86c 28 0d
; **************************************************************
;
; Fill lower 32K eith 0e5h - this is CP/M default data on a
; blank disk
;
; **************************************************************
ld hl,$0800 ; c86e 21 00 08
ld (hl),$e5 ; c871 36 e5
ld d,h ; c873 54
ld e,l ; c874 5d
inc de ; c875 13
ld bc,$07ff ; c876 01 ff 07
ldir ; c879 ed b0
L_C87B:
; **************************************************************
;
; Copy the code at L_C8A1 to 0100h in the expansion ram and then
; jump to 0115h so we can test upper expansion ram
;
; **************************************************************
ld hl,L_C8A1 ; c87b 21 a1 c8
ld de,$0100 ; c87e 11 00 01
ld bc,$003f ; c881 01 3f 00
ldir ; c884 ed b0
ld hl,L_C88C ; c886 21 8c c8
jp $0115 ; c889 c3 15 01
L_C88C:
.db 021h ; c88c 21
L_C88D:
; **************************************************************
;
; No RAM disk so save setting and switch back normal RAM
;
; **************************************************************
ld c,$ff ; c88d 0e ff
ld a,$01 ; c88f 3e 01
out (MEMBANK),a ; c891 d3 7f
ld a,c ; c893 79
ld (RAMDISK),a ; c894 32 4d 00
; **************************************************************
;
; Jump to BIOS Cold Boot at 0da00h
;
; **************************************************************
jp $da00 ; c897 c3 00 da
L_C89A:
; **************************************************************
;
; Error loading track - clean stack and try again
;
; **************************************************************
pop de ; c89a d1
pop bc ; c89b c1
pop af ; c89c f1
pop hl ; c89d e1
jp L_C831 ; c89e c3 31 c8
L_C8A1:
; **************************************************************
;
; Fill upper expansion RAM - this code is copied to 0100h in the
; expansion RAM lower 32k and executed there
;
; **************************************************************
ld a,$0a ; c8a1 3e 0a
out (MEMBANK),a ; c8a3 d3 7f
ld ($0080),bc ; c8a5 ed 43 80 00
ld bc,$0400 ; c8a9 01 00 04
ldir ; c8ac ed b0
ld a,$02 ; c8ae 3e 02
out (MEMBANK),a ; c8b0 d3 7f
ld hl,($0080) ; c8b2 2a 80 00
jp (hl) ; c8b5 e9
L_C8B6:
; **************************************************************
;
; Entry to fill the upper RAM - this is 0115h
;
; **************************************************************
ld ($0080),hl ; c8b6 22 80 00
ld hl,($0082) ; c8b9 2a 82 00
ld de,$14e9 ; c8bc 11 e9 14
or a ; c8bf b7
sbc hl,de ; c8c0 ed 52
jr z,$c8b2 ; c8c2 28 ee
ld a,$0e ; c8c4 3e 0e
out (MEMBANK),a ; c8c6 d3 7f
ld hl,($8000) ; c8c8 2a 00 80
ld de,$ca53 ; c8cb 11 53 ca
or a ; c8ce b7
sbc hl,de ; c8cf ed 52
jr nz,$c8ae ; c8d1 20 db
ld hl,$8002 ; c8d3 21 02 80
ld de,$0800 ; c8d6 11 00 08
ld bc,$7800 ; c8d9 01 00 78
ldir ; c8dc ed b0
jr $c8ae ; c8de 18 ce
.text " "
.text " Internal R"
.text "ev. 1.50 July 5"
.text ", 1984 (c) 19"
.text "83,1984, Coleco "
.text "Industries Inc. "
L_C940:
.db 0 ; c940
L_C941:
.db 0 ; c941
L_C942:
.db 0 ; c941
L_C943:
.db 0 ; c943
L_C944:
.db 0 ; c944
L_C945:
.db 0 ; c945
L_C946:
; **************************************************************
;
; Data checking
;
; **************************************************************
push hl ; c946 e5
ld a,(hl) ; c947 7e
cp c ; c948 b9
jr nz,L_C953 ; c949 20 08
inc hl ; c94b 23
ld a,(hl) ; c94c 7e
cp e ; c94d bb
jr nz,L_C953 ; c94e 20 03
inc hl ; c950 23
ld a,(hl) ; c951 7e
cp d ; c952 ba
L_C953:
pop hl ; c953 e1
ret ; c954 c9
L_C955:
; **************************************************************
;
; Load H blocks of data starting at block BC to memory address DE
;
; **************************************************************
push de ; c955 d5
push bc ; c956 c5
push af ; c957 f5
pop bc ; c958 c1
pop de ; c959 d1
ld a,(L_C940) ; c95a 3a 40 c9
cp b ; c95d b8
jr nz,L_C968 ; c95e 20 08
ld hl,(L_C941) ; c960 2a 41 c9
or a ; c963 b7
sbc hl,de ; c964 ed 52
jr z,L_C98E ; c966 28 26
L_C968:
ld c,b ; c968 48
ld a,b ; c969 78
ld (L_C940),a ; c96a 32 40 c9
ld (L_C941),de ; c96d ed 53 41 c9
ld hl,L_C943 ; c971 21 43 c9
call L_C946 ; c974 cd 46 c9
ld b,$02 ; c977 06 02
push bc ; c979 c5
jr z,L_C983 ; c97a 28 07
pop bc ; c97c c1
L_C97D:
push bc ; c97d c5
call L_C9C8 ; c97e cd c8 c9
jr nc,L_C9C5 ; c981 30 42
L_C983:
ld a,(L_C940) ; c983 3a 40 c9
call L_C9EC ; c986 cd ec c9
jr nc,L_C9C5 ; c989 30 3a
pop bc ; c98b c1
djnz L_C97D ; c98c 10 ef
L_C98E:
pop de ; c98e d1
ld hl,MEMLOC1 ; c98f 21 3b ee
ld bc,$0400 ; c992 01 00 04
ldir ; c995 ed b0
ld hl,(L_C941) ; c997 2a 41 c9
inc hl ; c99a 23
ld ($c944),hl ; c99b 22 44 c9
ld a,(L_C940) ; c99e 3a 40 c9
ld (L_C943),a ; c9a1 32 43 c9
call L_CA4F ; c9a4 cd 4f ca
jr nc,L_C9B9 ; c9a7 30 10
ld a,(hl) ; c9a9 7e
or a ; c9aa b7
jp p,L_C9B9 ; c9ab f2 b9 c9
ld (hl),$01 ; c9ae 36 01
L_C9B0:
ld a,(hl) ; c9b0 7e
rla ; c9b1 17
jr nc,L_C9B0 ; c9b2 30 fc
or a ; c9b4 b7
jr z,L_C9BE ; c9b5 28 07
ld (hl),$01 ; c9b7 36 01
L_C9B9:
xor a ; c9b9 af
ld (L_C943),a ; c9ba 32 43 c9
ret ; c9bd c9
L_C9BE:
ld hl,L_C943 ; c9be 21 43 c9
jp L_C9CF ; c9c1 c3 cf c9
pop bc ; c9c4 c1
L_C9C5:
pop bc ; c9c5 c1
pop bc ; c9c6 c1
ret ; c9c7 c9
L_C9C8:
ld hl,L_C940 ; c9c8 21 40 c9
xor a ; c9cb af
ld (L_C943),a ; c9cc 32 43 c9
L_C9CF:
ld a,$04 ; c9cf 3e 04
ld (L_C9E6),a ; c9d1 32 e6 c9
rra ; c9d4 1f
ld a,(hl) ; c9d5 7e
inc hl ; c9d6 23
ld e,(hl) ; c9d7 5e
inc hl ; c9d8 23
ld d,(hl) ; c9d9 56
ld hl,MEMLOC1 ; c9da 21 3b ee
ld bc,$0000 ; c9dd 01 00 00
push af ; c9e0 f5
push de ; c9e1 d5
push hl ; c9e2 e5
call L_CA22 ; c9e3 cd 22 ca
L_C9E6:
nop ; c9e6 00
pop hl ; c9e7 e1
pop de ; c9e8 d1
pop bc ; c9e9 c1
ld a,b ; c9ea 78
ret ; c9eb c9
L_C9EC:
push af ; c9ec f5
call L_CA4F ; c9ed cd 4f ca
pop bc ; c9f0 c1
ld a,$44 ; c9f1 3e 44
ret nc ; c9f3 d0
L_C9F4:
ld a,(hl) ; c9f4 7e
rlca ; c9f5 07
jr nc,L_C9F4 ; c9f6 30 fc
ld (hl),$01 ; c9f8 36 01
L_C9FA:
ld a,(hl) ; c9fa 7e
or a ; c9fb b7
jp p,L_C9FA ; c9fc f2 fa c9
cp $9b ; c9ff fe 9b
jr z,$c9f8 ; ca01 28 f5
xor $80 ; ca03 ee 80
ld a,$66 ; ca05 3e 66
ret nz ; ca07 c0
ld c,$f0 ; ca08 0e f0
ld a,b ; ca0a 78
and c ; ca0b a1
ld a,c ; ca0c 79
jr nz,L_CA10 ; ca0d 20 01
cpl ; ca0f 2f
L_CA10:
ld bc,$0014 ; ca10 01 14 00
push hl ; ca13 e5
add hl,bc ; ca14 09
and (hl) ; ca15 a6
pop hl ; ca16 e1
ret nz ; ca17 c0
scf ; ca18 37
ret ; ca19 c9
L_CA1A:
pop bc ; ca1a c1
pop bc ; ca1b c1
pop bc ; ca1c c1
pop bc ; ca1d c1
pop bc ; ca1e c1
pop hl ; ca1f e1
inc hl ; ca20 23
jp (hl) ; ca21 e9
L_CA22:
push af ; ca22 f5
push bc ; ca23 c5
push de ; ca24 d5
ld de,$0400 ; ca25 11 00 04
push de ; ca28 d5
push hl ; ca29 e5
call L_C9EC ; ca2a cd ec c9
jr nc,L_CA1A ; ca2d 30 eb
push hl ; ca2f e5
ex de,hl ; ca30 eb
inc de ; ca31 13
ld hl,$0002 ; ca32 21 02 00
add hl,sp ; ca35 39
ld bc,$0008 ; ca36 01 08 00
ldir ; ca39 ed b0
inc hl ; ca3b 23
ld a,(hl) ; ca3c 7e
inc hl ; ca3d 23
rrca ; ca3e 0f
rrca ; ca3f 0f
rrca ; ca40 0f
rrca ; ca41 0f
and $0f ; ca42 e6 0f
ld (de),a ; ca44 12
pop de ; ca45 d1
ld sp,hl ; ca46 f9
ex de,hl ; ca47 eb
pop de ; ca48 d1
ld a,(de) ; ca49 1a
inc de ; ca4a 13
push de ; ca4b d5
ld (hl),a ; ca4c 77
scf ; ca4d 37
ret ; ca4e c9
L_CA4F:
; **************************************************************
;
; Setup processor control block and device control blocks
;
; **************************************************************
ld hl,$fec3 ; ca4f 21 c3 fe
ld b,(hl) ; ca52 46
inc b ; ca53 04
dec b ; ca54 05
jr z,L_CA6B ; ca55 28 14
ld hl,$fed4 ; ca57 21 d4 fe
ld de,$0015 ; ca5a 11 15 00
and $0f ; ca5d e6 0f
L_CA5F:
cp (hl) ; ca5f be
jr z,L_CA65 ; ca60 28 03
add hl,de ; ca62 19
djnz L_CA5F ; ca63 10 fa
L_CA65:
ld de,$fff0 ; ca65 11 f0 ff
add hl,de ; ca68 19
scf ; ca69 37
ret z ; ca6a c8
L_CA6B:
ld a,$9b ; ca6b 3e 9b
or a ; ca6d b7
ret ; ca6e c9
; **************************************************************
;
; The following appears to be left from development
; as it is not referenced any where
;
; **************************************************************
.text "PAM's face" ; ca6f
; **************************************************************
;
; This is supposed to be a bitmap format of PAM's face Not sure
; what format that would be as there really was no graphic format
; then.
;
; **************************************************************
.db 027h,03ah,069h,078h,06ah,063h,06ah
.db 06ah,02bh,03fh,063h,04ch,058h,043h,065h
.db 061h,061h,071h,04fh,061h,034h,062h,047h
.db 047h,067h,041h,052h,052h,024h,038h,024h
.db 033h,07ch,06bh,041h,02ch,07bh,078h,078h
.db 06ch,078h,072h,072h,072h,06ah,03fh,04ch
.db 073h,02ah,046h,068h,046h,04bh,04bh,061h
.db 04bh,04bh,064h,070h,04bh,06fh,06fh,07ah
.db 046h,067h,041h,052h,029h,072h,067h,021h
.db 028h,03ah,021h,027h,02eh,02eh,02eh,02eh
.db 02eh,027h,03ch,06ah,04ch,06fh,02ah,04bh
.db 034h,033h,033h,050h,033h,025h,021h,02eh
.db 020h,02eh,03ah,03ah,060h,078h,06fh,02eh
.db 029h,058h,020h,020h,02eh,020h,020h,020h
.db 02eh,074h,07bh,02eh,020h,02eh,027h,03ch
.db 079h,049h,061h,033h,052h,038h,041h,07bh
.db 02eh,02eh,020h,027h,034h,038h,055h,077h
.db 071h,061h,02eh,02dh,075h,02eh,020h,02eh
.db 07ch,02eh,027h,07bh,05dh,06ch,05ch,02eh
.db 05ch,02ch,05fh,069h,063h,061h,05ah,052h
.db 023h,052h,046h,069h,07eh,03ah,029h,072h
.db 063h,062h,024h,024h,052h,03dh,02eh,029h
.db 02fh,028h,03ah,03ah,03ah,05ch,02fh,05ch
.db 03ah,03ah,03ah,03ah,029h,07bh,072h,02bh
.db 056h,04bh,045h,023h,023h,024h,041h,055h
.db 061h,034h,067h,041h,038h,024h,024h,023h
.db 037h,020h,02eh,03ch,069h,07bh,072h,072h
.db 069h,03bh,069h,07dh,06ch,074h,02bh,03fh
.db 063h,079h,074h,063h,05dh,04fh,024h,023h
.db 023h,023h,023h
; **************************************************************
;
; Unsure if this is different or is a continuation of the data
; that is PAM's face
;
; **************************************************************
.text "RADWAR" ; cb63
.db 038h,024h,06ch,020h,02eh,076h,07bh
.db 03bh,07bh,07dh,06ch,06ch,078h,079h,078h
.db 074h,074h,063h,074h,078h,06ch,063h,063h
.db 043h,050h,023h,023h,038h,052h,052h,041h
.db 041h,039h,036h,041h,052h,044h,02eh,02eh
.db 03ah,029h,029h,03eh,069h,03bh,03eh,03dh
.db 03bh,029h,029h,03ah,05ch,028h,076h,06ch
.db 074h,05dh,031h,07ah,061h,045h,038h,041h
.db 05ah,051h,045h,057h,04dh,041h,052h,052h
.db 029h,020h,02ch,063h,02dh,05fh,03ah,03ah
.db 03ah,03ah,03ch,028h,03ch,03ah,03ah,05fh
.db 03ah,03ch,03eh,03ah,07dh,074h,043h,032h
.db 041h,052h,045h,035h,035h,044h,041h,052h
.db 024h,024h,046h,02eh,07ch,078h,05ah,07ch
.db 07eh,02fh,07eh,05fh,03ah,028h,029h,03eh
.db 028h,03dh,07dh,03bh,069h,069h,06ch,031h
.db 058h,034h,038h,023h,023h,023h,038h,024h
.db 024h,024h,038h,023h,041h,046h,04bh,026h
.db 050h,041h,000h,000h,000h,000h,000h,000h
.end