Files
RomWBW/Source/QPM/loader.asm
Wayne Warthen bb70c36b36 Improve QPM Build
The QPM portion of the build has been updated to dynamically combine the current CBIOS with the static QPM CCP and BDOS binaries.  This will keep the QPM system image up to date and avoid HBIOS version mismatch warnings.
2023-09-09 16:18:40 -07:00

272 lines
7.2 KiB
NASM

;===============================================================================
; LOADER.ASM
;
; BOOTLOADER FOR ROMWBW DISK OPERATING SYSTEMS.
;
; CP/M DISK FORMATS ALLOW FOR RESERVED TRACKS THAT CONTAIN AN IMAGE OF THE
; OPERATING SYSTEM TO BE LOADED WHEN THE DISK IS BOOTED. THE OPERATING SYSTEM
; IMAGE ITSELF IS NORMALLY PREFIXED BY A 1-N SECTORS CONTAINING OS BOOTSTRAP
; CODE AND DISK METADATA.
;
; THE RETROBREW COMPUTING GROUP HAS BEEN USING A CONVENTION OF PREFIXING THE
; OS IMAGE WITH 3 SECTORS (512 BYTES X 3 FOR A TOTAL OF 1536 BYTES):
;
; SECTOR 1: IBM-PC STYLE BOOT BLOCK CONTAINING BOOTSTRAP,
; PARTITION TABLE, AND BOOT SIGNATURE
; SECTOR 2: RESERVED
; SECTOR 3: METADATA
;
; THE HARDWARE BIOS IS EXPECTED TO READ AND LOAD THE FIRST TWO SECTORS FROM THE
; DISK TO MEMORY ADDRESS $8000 AND JUMP TO THAT LOCATION TO BEGIN THE BOOT
; PROCESS. THE BIOS IS EXPECTED TO VERIFY THAT A STANDARD BOOT SIGNATURE
; OF $55, $AA IS PRESENT AT OFFSET $1FE-$1FF. IF THE SIGNATURE IS NOT FOUND,
; THE BIOS SHOULD ASSUME THE DISK HAS NOT BEEN PROPERLY INITIALIZED AND SHOULD
; NOT JUMP TO THE LOAD ADDRESS.
;
;===============================================================================
;
#INCLUDE "../ver.inc"
;
SYS_ENT .EQU $E600 ; SYSTEM (OS) ENTRY POINT ADDRESS
SYS_LOC .EQU $D000 ; STARTING ADDRESS TO LOAD SYSTEM IMAGE
SYS_END .EQU $FE00 ; ENDING ADDRESS OF SYSTEM IMAGE
;
SEC_SIZE .EQU 512 ; DISK SECTOR SIZE
BLK_SIZE .EQU 128 ; OS BLOCK/RECORD SIZE
;
PREFIX_SIZE .EQU (SEC_SIZE * 3) ; 3 SECTORS
;
META_SIZE .EQU 32 ; SEE BELOW
META_LOC .EQU (PREFIX_SIZE - META_SIZE)
;
PT_LOC .EQU $1BE
PT_SIZ .EQU $40
;
;-------------------------------------------------------------------------------
; SECTOR 1
;
; THIS SECTOR FOLLOWS THE CONVENTIONS OF AN IBM-PC MBR CONTAINING THE OS
; BOOTSTRAP CODE, PARTITION TABLE, AND BOOT SIGNATURE
;
;----------------------------------------------------------------------------
;
; THE FOLLOWING BOOTSTRAP CODE IS BUILT TO ASSUME IT WILL BE EXECUTED AT A STARTING
; ADDRESS OF $8000. THIS CODE IS *ONLY* FOR UNA. THE ROMWBW ROM BOOTLOADER
; USES THE METADATA TO LOAD THE OS DIRECTLY.
;
.ORG $8000
JR BOOT
;
BOOT:
LD DE,STR_LOAD ; LOADING STRING
CALL PRTSTR ; PRINT
CALL PRTDOT ; PROGRESS
;
LD BC,$00FC ; UNA FUNC: GET BOOTSTRAP HISTORY
CALL $FFFD ; CALL UNA
JR NZ,ERROR ; HANDLE ERROR
CALL PRTDOT ; PROGRESS
LD B,L ; MOVE BOOT UNIT ID TO B
;
LD C,$41 ; UNA FUNC: SET LBA
LD DE,0 ; HI WORD ALWAYS ZERO
LD HL,3 ; IMAGE STARTS AT FOURTH SECTOR
CALL $FFFD ; SET LBA
JR NZ,ERROR ; HANDLE ERROR
CALL PRTDOT ; PROGRESS
;
LD C,$42 ; UNA FUNC: READ SECTORS
LD DE,$D000 ; STARTING ADDRESS FOR IMAGE
LD L,22 ; READ 22 SECTORS
CALL $FFFD ; DO READ
JR NZ,ERROR ; HANDLE ERROR
CALL PRTDOT ; PROGRESS
;
LD DE,STR_DONE ; DONE MESSAGE
CALL PRTSTR ; PRINT IT
;
LD D,B ; PASS BOOT UNIT TO OS
LD E,0 ; ASSUME LU IS ZERO
JP SYS_ENT ; GO TO SYSTEM
;
PRTCHR:
PUSH BC
PUSH DE
LD BC,$0012 ; UNIT 0, WRITE CHAR
LD E,A ; CHAR TO PRINT
CALL $FFFD ; PRINT
POP DE
POP BC
RET
;
PRTSTR:
PUSH BC
PUSH HL
LD BC,$0015 ; UNIT 0, WRITE CHARS UNTIL TERMINATOR
LD L,0 ; TERMINATOR IS NULL
CALL $FFFD ; PRINT
POP HL
POP BC
RET
;
PRTDOT:
LD A,'.' ; DOT CHARACTER
JR PRTCHR ; PRINT AND RETURN
;
; PRINT THE HEX BYTE VALUE IN A
;
PRTHEXBYTE:
PUSH AF
PUSH DE
CALL HEXASCII
LD A,D
CALL PRTCHR
LD A,E
CALL PRTCHR
POP DE
POP AF
RET
;
; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE
;
HEXASCII:
LD D,A
CALL HEXCONV
LD E,A
LD A,D
RLCA
RLCA
RLCA
RLCA
CALL HEXCONV
LD D,A
RET
;
; CONVERT LOW NIBBLE OF A TO ASCII HEX
;
HEXCONV:
AND $0F ;LOW NIBBLE ONLY
ADD A,$90
DAA
ADC A,$40
DAA
RET
;
ERROR:
LD DE,STR_ERR ; POINT TO ERROR STRING
CALL PRTSTR ; PRINT IT
HALT ; HALT
;
; DATA
;
STR_LOAD .DB "\r\nLoading",0
STR_DONE .DB "\r\n",0
STR_ERR .DB " Read Error!",0
;
.ORG $ - $8000 ; BACK TO ABSOLUTE ADDRESS
;
.FILL PT_LOC - $,0 ; FILL TO START OF PARTITION TABLE
;
; STANDARD IBM-PC PARTITION TABLE. ALTHOUGH A
; PARTITION TABLE IS NOT RELEVANT FOR A FLOPPY DISK, IT DOES NO HARM.
; THE CONTENTS OF THE PARTITION TABLE CAN BE MANAGED BY FDISK80.
;
; BELOW WE ALLOW FOR 32 SLICES OF ROMWBW CP/M FILESYSTEMS
; FOLLOWED BY A FAT16 PARTITION. THE SLICES FOLLOW THE ORIGINAL
; HD512 ROMWBW FORMAT. IF THE DISK IS USING HD1K, A SEPARATE
; PARTITION TABLE WILL BE IN PLACE AND RENDER THIS PARTITION TABLE
; IRRELEVANT.
;
; THE CYL/SEC FIELDS ENCODE CYLINDER AND SECTOR AS:
; CCCCCCCC:CCSSSSSS
; 76543210:98543210
;
PART0:
.DB 0 ; ACTIVE IF $80
.DB 0 ; CHS START ADDRESS (HEAD)
.DW 0 ; CHS START ADDRESS (CYL/SEC)
.DB 0 ; PART TYPE ID
.DB 0 ; CHS LAST ADDRESS (HEAD)
.DW 0 ; CHS LAST ADDRESS (CYL/SEC)
.DW 0,0 ; LBA FIRST (DWORD)
.DW 0,0 ; LBA COUNT (DWORD)
PART1:
.DB 0 ; ACTIVE IF $80
.DB 0 ; CHS START ADDRESS (HEAD)
.DW %1111111111000001 ; CHS START ADDRESS (CYL/SEC)
.DB 6 ; PART TYPE ID
.DB 15 ; CHS LAST ADDRESS (HEAD)
.DW %1111111111010000 ; CHS LAST ADDRESS (CYL/SEC)
.DW $4000,$0010 ; LBA FIRST (DWORD)
.DW $0000,$000C ; LBA COUNT (DWORD)
PART2:
.DB 0 ; ACTIVE IF $80
.DB 0 ; CHS START ADDRESS (HEAD)
.DW 0 ; CHS START ADDRESS (CYL/SEC)
.DB 0 ; PART TYPE ID
.DB 0 ; CHS LAST ADDRESS (HEAD)
.DW 0 ; CHS LAST ADDRESS (CYL/SEC)
.DW 0,0 ; LBA FIRST (DWORD)
.DW 0,0 ; LBA COUNT (DWORD)
PART3:
.DB 0 ; ACTIVE IF $80
.DB 0 ; CHS START ADDRESS (HEAD)
.DW 0 ; CHS START ADDRESS (CYL/SEC)
.DB 0 ; PART TYPE ID
.DB 0 ; CHS LAST ADDRESS (HEAD)
.DW 0 ; CHS LAST ADDRESS (CYL/SEC)
.DW 0,0 ; LBA FIRST (DWORD)
.DW 0,0 ; LBA COUNT (DWORD)
;
; THE END OF THE FIRST SECTOR MUST CONTAIN THE TWO BYTE BOOT SIGNATURE.
;
BOOTSIG .DB $55,$AA ; STANDARD BOOT SIGNATURE
;
;-------------------------------------------------------------------------------
; SECTOR 2
;
; THIS SECTOR HAS NOT BEEN DEFINED AND IS RESERVED.
;
;----------------------------------------------------------------------------
;
.FILL SEC_SIZE,0 ; JUST FILL SECTOR WITH ZEROES
;
;-------------------------------------------------------------------------------
; SECTOR 3
;
; OS AND DISK METADATA
;
;----------------------------------------------------------------------------
;
.FILL (BLK_SIZE * 3),0 ; FIRST 384 BYTES ARE NOT YET DEFINED
;
; THE FOLLOWING TWO BYTES ARE AN ADDITIONAL SIGNATURE THAT IS VERIFIED BY
; SOME HARDWARE BIOSES.
;
PR_SIG .DB $5A,$A5 ; SIGNATURE GOES HERE
;
.FILL (META_LOC - $),0
;
; METADATA
;
PR_WP .DB 0 ; (1) WRITE PROTECT BOOLEAN
PR_UPDSEQ .DW 0 ; (2) PREFIX UPDATE SEQUENCE NUMBER (DEPRECATED?)
PR_VER .DB RMJ,RMN,RUP,RTP ; (4) OS BUILD VERSION
PR_LABEL .DB "Unlabeled$$$$$$$","$" ; (17) DISK LABEL (EXACTLY 16 BYTES!!!)
.DW 0 ; (2) DEPRECATED
PR_LDLOC .DW SYS_LOC ; (2) ADDRESS TO START LOADING SYSTEM
PR_LDEND .DW SYS_END ; (2) ADDRESS TO STOP LOADING SYSTEM
PR_ENTRY .DW SYS_ENT ; (2) ADDRESS TO ENTER SYSTEM (OS)
;
#IF (META_SIZE != ($ - META_LOC))
.ECHO "META_SIZE VALUE IS WRONG!!!\r\n"
!!!
#ENDIF
;
#IF ($ != PREFIX_SIZE)
.ECHO "LOADER PREFIX IS WRONG SIZE!!!\r\n"
!!!
#ENDIF
;
.END