JonB
Veteran Member
Hi
I have decoded the Superbrain's ACT boot code. It's really simple. All it does is copy the first 16 bytes from the hard drive (Drive 0, Head 0, Track 0, Sector 0) to a specific location in memory, then jumps to it.
So (comments are mine):-
There are a few interesting things about this:
Just for comparison, here's the CMC boot code.
I have decoded the Superbrain's ACT boot code. It's really simple. All it does is copy the first 16 bytes from the hard drive (Drive 0, Head 0, Track 0, Sector 0) to a specific location in memory, then jumps to it.
So (comments are mine):-
Code:
c3A3 AF XOR A ; a=0
c3a4 D3CD OUT (0CDH),A ; Drive 0
c3a6 D3C9 OUT (0C9H),A ; Track 0
c3a8 D3CA OUT (0CAH),A ; Head 0
c3aa D3CB OUT (0CBH),A ; Sector 0
c3ac DBC8 IN A,(0C8H) ; Wait ready
c3ae 87 ADD A,A ;
c3af F2ACC3 JP P,0C3ACH ; loop back if not
c3b2 3E06 LD A,06H ; Issue Home disk cmd
c3b4 D3C8 OUT (0C8H),A ;
c3b6 DBC8 IN A,(0C8H) ; wait for home bit (guess)
c3b8 17 RLA ;
c3b9 DAB6C3 JP C,0C3B6H ; if bit 7 unset, loop back
c3bc 3E01 LD A,01H ; issue READSEC command
c3be D3C8 OUT (0C8H),A ;
c3c0 DBC8 IN A,(0C8H) ; get status
c3c2 E682 AND 82H ; AND 10000010
c3c4 FAC0C3 JP M,0C3C0H ; Negative (bit 7 set), loop back
c3c7 C230C3 JP NZ,0C330H ; Positive (bit 1 set), poll keyboard again
c3ca DBCC IN A,(0CCH) ; else it's Zero
c3cc 2180C7 LD HL,0C780H ; Copy 16 bytes from the drive to C780
c3cf DBCC IN A,(0CCH) ; get byte from drive buffer
c3d1 77 LD (HL),A ; copy to machine buffer
c3d2 2C INC L ; next byte
c3d3 C2CFC3 JP NZ,0C3CFH ; if it's < 16 loop for next byte
c3d6 C380C7 JP 0C780H ; done. Jump to the code
There are a few interesting things about this:
- It appears to use the same I/O addresses as the CMC International interface / drive.
- It is obviously an intermediate bootstrap. What code is in the the 16 bytes?
- There is a good chance that CMC HDD utilities will work with it, if any can be found.
- I can write code to interrogate it, once I have completed my mainboard repairs.
Just for comparison, here's the CMC boot code.
Code:
; Hard disk boot sector for Superbrain with:
;
; CP/M 2.2
; Intertec Superbrain DOS 3.2
; CMC hard disk BIOS ver 1.16
;
; 01/06/90 Dan Fandrich Original disassembly
; Added 'ERR' display routine
;
; Hard disk controller ports
;
HDCMD: EQU 0C8H ; Hard disk controller command port
HDSTAT: EQU 0C8H ; Hard disk controller status port
HDTRK: EQU 0C9H ; track number
HDHEAD: EQU 0CAH ; head number
HDSEC: EQU 0CBH ; sector number
HDDATA: EQU 0CCH ; data buffer
HDDRIV: EQU 0CDH ; driver number
;
; Hard disk controller commands
;
RDSEC: EQU 1 ; read a sector
HOME: EQU 6 ; home disk
;
; "Magic numbers"
;
BYTE1: EQU 0C3H ; first byte of CCP JMP 0CB5CH
BYTE2: EQU 1 ;05CH ; second byte of CCP
;BYTE3: EQU 0CBH ; third byte of CCP
;
CCPOFS: EQU 3 ; difference between BYTE3 and CCP load page
SCREEN EQU 0F800H ; start of screen
;
ORG 0C780H ; location that boot sector is loaded into
;
HDBOOT: XRA A
OUT HDDRIV ; drive 0
OUT HDTRK ; track 0
OUT HDHEAD ; head 0
OUT HDSEC ; sector 0
WREADY: IN HDSTAT ; wait for hard disk to become ready
ADD A
JP WREADY
MVI A,HOME ; home disk
OUT HDCMD
WHOME: IN HDSTAT ; wait for hard disk to home
RAL
JC WHOME
LXI B,8128H ; read 28H sectors
; skip first 81H-1 bytes in first sector
;
READSC: MVI A,RDSEC ; read the next sector
OUT HDCMD
WREAD: IN HDSTAT
RAL
JC WREAD ; wait until sector has been read
ANI 4
JNZ ERROR ; error in reading
ORA B
IN HDDATA ; get first byte (?)
JZ NXTBYT ; if this isn't the very first sector, read
; in all the bytes, otherwise skip the first
; 80H (this bootstrap loader)
SKPBYT: IN HDDATA ; read byte & skip it (usually)
DCR B
JNZ SKPBYT ; ignore 7FH bytes
CPI BYTE1 ; is byte 80H of sector 0 equal to the
; first byte of CCP? (JMP opcode)
JNZ ERROR ; no, CP/M is not installed
IN HDDATA ; get next byte
CPI BYTE2 ; compare with second byte of CCP
; (low byte of JMP)
JNZ ERROR ; jump to error if CP/M isn't installed
IN HDDATA ; get next byte (high byte of JMP address)
MOV D,A
SUI CCPOFS ; find high byte of CCP load address
MOV H,A ; H=high byte of CCP address
MOV L,B ; L=0
MVI M,BYTE1 ; store the JMP xx5CH that was ignored above
INX H
MVI M,BYTE2
INX H
MOV M,D
INX H
XCHG
LXI H,15FDH ; add 15FDH to HL
DAD D ; HL points to BIOS cold boot entry point
MVI B,7DH ; 7DH more bytes to read in this first sector
;
NXTBYT: IN HDDATA ; read the next byte
STAX D ; store it in memory
INX D ; point to next address
DCR B ; decrement byte count
JNZ NXTBYT ; go read next byte
;
IN HDSEC ; get current sector
INR A ; point to next sector
ANI 1FH
OUT HDSEC
JNZ NXTSEC ; read the next sector
INR A ; read from head 1
OUT HDHEAD
NXTSEC: DCR C ; one less sector to read
JNZ READSC ; if there's more, go read it
PCHL ; jump to routine at HL
;
; This error routine added to display the message 'ERR' on the screen
; in the case of an error
;
ERROR: LXI H,'ER' OR 8080H ; first part of flashing 'ERR' string
SHLD SCREEN+70 ; display it on the screen
MOV A,H
STA SCREEN+72 ; display second 'R' on screen
;
ERR1: JMP ERR1 ; enter endless loop on error
;
Last edited: