;********** wboot.s -- Olivetti bootstrap writer***** ;* ;* 821013 S. Savitzky (Zilog) -- adapt for nonseg. ;* 820930 S. Savitzky (Zilog) -- created ;* ;**************************************************** __text: .sect ;**************************************************** ;* ;* NOTE -- THIS CODE IS HIGHLY SYSTEM-DEPENDENT ;* ;* This module contains both the bootstrap ;* writer, and the code that receives control ;* after being booted. ;* ;* The main function of the latter is to make ;* sure that the system, whose entry point is ;* called "bios", is passed a valid stack ;* and PSA pointer. ;* ;* Although this code runs segmented, it must ;* be linked with non-segmented code, so it ;* looks rather odd. ;* ;**************************************************** ;**************************************************** ;* ;* Bootstrap Writer for P-CP/M on the Olivetti M20. ;* ;* This program puts out a bootstrap file in the ;* Olivetti's peculiar format, which has a lot of ;* Olivetti's file system in it. ;* ;* Track 0 is unused except for sector 0, since ;* it is single density and thus has smaller ;* sectors. ;* ;* A total of 10 tracks are reserved from CP/M, ;* leaving 9 tracks for the system proper. ;* ;* The first sector on track 1 is the PCOS file ;* descriptor block; the second is the boot file ;* header and the start of the system code. ;* ;* This leaves something under 28K for the ;* system (BIOS+BDOS+CCP). It is assumed that ;* the system starts at its lowest address, ;* and that data follows immediately after code. ;* ;* For now, we assume that the system starts at ;* <<11>>0000 (hex) ;* ;**************************************************** ;**************************************************** ;* ;* Externals ;* ;**************************************************** .global bios .global _wboot ;**************************************************** ;* ;* Constants ;* ;**************************************************** SYSTEM .equ 0B000000h ; system address SYSSTK .equ SYSTEM+0BFFEh ; system stack top rtc_ext .equ 02000022h ; real-time clock ; ext. call addr BPT .equ 16 ; #blocks in a track BPS .equ 256 ; #bytes in a sector NBLKS .equ 9*16 ; #blocks in boot HDRSIZE .equ 24 ; #bytes in header FILSIZE .equ 256*(NBLKS-1) ; file data size SYSSIZE .equ FILSIZE-HDRSIZE ; total system size S1SIZE .equ BPS-HDRSIZE ; data in sector 1 SEG4 .equ 04000000h SEG2 .equ 02000000h SYSPSA .equ SEG2+100h ; system PSA BOOTPSA .equ SEG4+100h ; PSA in PROM for boot sscall .macro ;short segmented call .word 05f00h .word ?1 .endm ;**************************************************** ;* ;* Entry Points and post-boot Initialization ;* ;**************************************************** ;* transfer vector jr wboot jr wrboot jr entry ;* post-boot init. entry: ;SEGMENTED DI VI,NVI ldl rr14, #SYSSTK ; init stack pointer ldl rr2, #SYSPSA ; copy PROM's PSA ldctl r4, psapseg ldctl r5, psapoff ld r0, #570/2 ldir @r2, @r4, r0 ldl rr2, #SYSPSA ; shift PSA pointer ldctl psapseg, r2 ldctl psapoff, r3 ld r2,#142h ;CROCK-- turn off ld r3,#1feh ; usart interrupts out @r2,r3 ldar r2, $ ; go ld r3,#bios jp @r2 wboot: ldar r2, $ ld r3,#_wboot jp @r2 ;**************************************************** ;* ;* Bootstrap Writer ;* Although written as if non-segmented, ;* this code actually has to run segmented. ;* ;**************************************************** wrboot: ;* Init ldl rr2,#BOOTPSA ; psa ldctl psapseg, r2 ldctl psapoff, r3 ldl rr14,#SYSSTK ; stack ptr ldl rr2,#rtc_ext ; disable real-time ld @r2,#0ffffh ; clock ext call EI VI,NVI ; interrupts ld r2,#0202h ; type 2 drives & disks ldl rr4,#SEG2+0030h ; (kludge for Olivetti) ld @r4,r2 inc r5,#2 ld @r4,r2 sscall 047Ah ; screen init sscall 046Eh ; clock init sscall 0462h ; disk init ldar r12, msg2 ; "writing ..." sscall 0486h ; put message ;* Write track 0 sector 0 ld r8,#1 ld r9,#0 ldar r10,T0S0 calr Write ;* copy data into first sector ldl rr2,#SYSTEM ldar r4,s1data ld r0, #S1SIZE/2 ldir @r4,@r2,r0 ;* write FDB and first data sector ld r8,#2 ld r9,#BPT ldar r10,T1S0 calr Write ;* write rest of system. ld r8,#NBLKS-2 ld r9,#BPT+2 ldl rr10,#SYSTEM+S1SIZE calr Write ;* hang up. ldar r12, msg1 ; "done ..." sscall 0486h ; put message hang: jr hang ;*------------- W R I T E D I S K ------------------ Write: ; write sectors to disk. ; r8 = block count ; r9 = block number ; rr10= data address ; add parameters for PROM routine ldb rh7,#0 ; rh7 = drive # ldb rl7,#1 ; rl7 = command sscall 0468h ; do it ret ;*--------------- messages ----------------------- ;* Note: must be in same program section as code msg1: .byte " Done " msg2: .byte "Writing Bootstrap..." .byte 0 0 ;**************************************************** ;* ;* Track 0 Sector 0 ;* ;* This sector contains the pointer to the ;* bootstrap file's FDB. ;* ;**************************************************** T0S0: .byte 0 ; major version .byte 0 ; minor version .word 40 ; #tracks/surface ?? 35 ?? .byte 2 ; #surfaces .byte 16 ; #sectors/track .word 256 ; #bytes/sector .word 40 ; ??? track # of control blk .word 38h ; ??? vdb size .word 136 ; ??? block bitmap size .byte 30 ; ??? directory bitmap size .byte 0 ; ??? track count direction ??? .byte 0 ; number of uses (if 0, no boot) .byte 0 ; copy protection (OFF) .byte 0 ; boot block read protect (OFF) .byte 0 ; boot block write protect (OFF) .word 0 ; soft error count .word 0 ; hard error count .word 0 ; lowest useable track side 0 ?1? .word 39 ; highest .word 0 ; side 1 .word 39 ; .word 0 ; side 2 .word 0 ; .word 0 ; side 3 .word 0 ; .long BPT ; BOOT FILE FDB BLOCK NUMBER .byte "PCOS" ; system name?? .long 2 ; ??? directory start addr .long 0 ; ??? drive data ??? .long 0 .long 0 .long 0 .long 0 .word 1 ; disk valid (VALID) .byte 0 ; drive number required ??? .byte 0 ; disk open .byte 0 ; format major version # .byte 0 ; minor .byte 2 ; disk type = 320Kb .byte 0 ; 27 bytes of nothing .byte 0 ; 26 .byte 0 ; 25 .byte 0 ; 24 .byte 0 ; 23 .byte 0 ; 22 .byte 0 ; 21 .byte 0 ; 20 .byte 0 ; 19 .byte 0 ; 18 .byte 0 ; 17 .byte 0 ; 16 .byte 0 ; 15 .byte 0 ; 14 .byte 0 ; 13 .byte 0 ; 12 .byte 0 ; 11 .byte 0 ; 10 .byte 0 ; 9 .byte 0 ; 8 .byte 0 ; 7 .byte 0 ; 6 .byte 0 ; 5 .byte 0 ; 4 .byte 0 ; 3 .byte 0 ; 2 .byte 0 ; 1 .block 22 ; forgotten, aparently ;**************************************************** ;* ;* Track 1 Sector 0 ;* ;* This sector is the FDB for the bootstrap ;* file. It has a single extent. ;* ;**************************************************** T1S0: .long FILSIZE ; file length in bytes .word 1 ; #extents .byte 0 ; 14 password (14 bytes) .byte 0 ; 13 .byte 0 ; 12 .byte 0 ; 11 .byte 0 ; 10 .byte 0 ; 9 .byte 0 ; 8 .byte 0 ; 7 .byte 0 ; 6 .byte 0 ; 5 .byte 0 ; 4 .byte 0 ; 3 .byte 0 ; 2 .byte 0 ; 1 .word 0 ; ??? verify location ??? .byte 0 ; write protect .byte 0 ; future .long BPT+1 ; STARTING BLOCK OF EXTENT .word NBLKS-1 ; NUMBER OF BLOCKS IN EXTENT .block 222 ; other extents .long 0 ; next fdb ;**************************************************** ;* ;* Track 1 Sector 1 ;* ;* This sector is the header for the bootstrap ;* file, followed by the first S1SIZE bytes of ;* data, which are copied in. ;* ;**************************************************** T1S1: .word 0101h ; magic number .byte "PCPM" ; identifier .byte "x01." .byte "01" .long SYSTEM+6 ; starting addr. .word 1 ; #code blocks .long SYSTEM ; load address .word SYSSIZE/2 ; #words s1data .block S1SIZE ; data area