BIOSSZ  EQU     512
;
TPA     EQU     100H
;
;
;       PASCAL BOOT MAINTENCE PROGRAM
;
;               BOOTER MAY BE READ IN FROM CURRENT PASCAL DISK AND MOVED
;               ONTO ANY NUMBER OF NEW DISKETTES
;
;       THIS PROGRAM PROVIDED COURTESY OF NORTHWEST MICROCOMPUTER SYSTEMS, INC.
;
;
BOOT    EQU     0
BDOS    EQU     5
RDCON   EQU     1
WRBUF   EQU     9
START   EQU     900H
ENDPT   EQU     START+128+256+768+BIOSSZ        ;BOOT+PINIT+SPARE+BIOS
NSECTS  EQU     (ENDPT-START)/128
FSTSCT  EQU     1
;
CR      EQU     0DH
LF      EQU     0AH
EOM     EQU     '$'
;
;
;
       ORG     TPA
;
;
       LXI     SP,STACK
MAIN:
       CALL    SAY$TITLE
       CALL    GET$BOOTER
       CALL    PUT$BOOTER
       JMP     REBOOT
;
;
HOME:                           ;HOME DISK
       LHLD    BOOT+1
       MVI     L,18H
       PCHL
;
SELDSK:                         ;SELECT DISK
       LHLD    BOOT+1
       MVI     L,1BH
       PCHL
;
SETTRK:                         ;SET TRACK
       LHLD    BOOT+1
       MVI     L,1EH
       PCHL
;
SETSEC:                         ;SET SECTOR
       LHLD    BOOT+1
       MVI     L,21H
       PCHL
;
SETDMA:                         ;SET DMA ADDRESS
       LHLD    BOOT+1
       MVI     L,24H
       PCHL
;
READ:                           ;READ A SECTOR
       LHLD    BOOT+1
       MVI     L,27H
       PCHL
;
WRITE:                          ;WRITE A SECTOR
       LHLD    BOOT+1
       MVI     L,2AH
       PCHL
;
;
SAY$TITLE:                      ;JUST SAY WHO WE ARE
       MVI     C,WRBUF
       LXI     D,HELLO$MSG
       CALL    BDOS
       RET
;
;
GET$BOOTER:                     ;MAYBE A BOOTER COMES IN
       MVI     C,WRBUF
       LXI     D,GET$MSG
       CALL    BDOS
       CALL    CK$YES
       RC                      ;THAT'S ALL FOR HERE
       MVI     C,WRBUF
       LXI     D,READ$MSG      ;SAY HEY
       CALL    BDOS
       CALL    WAIT$FOR$RET    ;AND WAIT
       CALL    DO$READ
       RET                     ;DONE
;
;
PUT$BOOTER:                     ;DOES THE BOOTER GO OUT?
       MVI     C,WRBUF         ;ASK
       LXI     D,PUT$MSG
       CALL    BDOS
       CALL    CK$YES          ;IF THE ANSWER IS NOT YES
       RC                      ;LEAVE
PUT$AGAIN:                      ;ELSE START TO PUT
       MVI     C,WRBUF
       LXI     D,WRITE$MSG
       CALL    BDOS            ;DO ANOTHER CONFIRM MSG
       CALL    WAIT$FOR$RET    ;AND HOLD UP
       CALL    DO$WRITE        ;NOW PUT IT OUT
       MVI     C,WRBUF         ;IS THIS A LOOP?
       LXI     D,AGAIN$MSG
       CALL    BDOS
       CALL    CK$YES
       JNC     PUT$AGAIN       ;GUESS SO
       RET                     ;ALL DONE
;
;
REBOOT:                         ;PULL BACK CP/M
       MVI     C,WRBUF
       LXI     D,REBOOT$MSG
       CALL    BDOS
       CALL    WAIT$FOR$RET
       JMP     BOOT
;
;
CK$YES:                         ;CHECK FOR A YES RESPONSE
       MVI     C,RDCON
       CALL    BDOS
       CPI     03H             ;DON'T FORGET ^C
       JZ      BOOT
       CPI     'Y'             ;UPPER CASE
       RZ
       CPI     79H             ;AND LOWER
       RZ
       STC                     ;NOT THERE
       RET
;
;
WAIT$FOR$RET:                   ;HANG AROUND
       MVI     C,RDCON
       CALL    BDOS
       CPI     03H             ;TEST FOR REBOOT REQUEST
       JZ      BOOT
       CPI     CR              ;LEAVE WHEN READY
       JNZ     WAIT$FOR$RET
       RET
;
;
DO$READ:                        ;READ IN THE BOOTER
       MVI     C,0             ;SELECT DISK
       CALL    SELDSK
       CALL    HOME            ;MAKE SURE IT'S INITIALIZED
       LXI     B,START         ;SET WHERE WE START IN RAM
       LXI     D,NSECTS SHL 8 + FSTSCT ;SIZE AND THE FIRST SECTOR
DR$LOOP:                                ;THEN PUT IT OUT
       PUSH    B
       PUSH    D
       CALL    SETDMA
       POP     D
       MOV     C,E
       PUSH    D
       CALL    SETSEC
       CALL    READ
       POP     D
       POP     B
       LXI     H,128
       DAD     B
       MOV     B,H
       MOV     C,L
       INR     E
       DCR     D
       JNZ     DR$LOOP
       RET
;
;
DO$WRITE:                       ;WRITE OUT THE BOOTER
       MVI     C,0             ;SELECT THE DISK
       CALL    SELDSK
       CALL    HOME
       LXI     B,START
       LXI     D,NSECTS SHL 8 + FSTSCT
DW$LOOP:                        ;ALL PARAMS SET - RUN IT OUT
       PUSH    B
       PUSH    D
       CALL    SETDMA
       POP     D
       MOV     C,E
       PUSH    D
       CALL    SETSEC
       CALL    WRITE
       POP     D
       POP     B
       LXI     H,128
       DAD     B
       MOV     B,H
       MOV     C,L
       INR     E
       DCR     D
       JNZ     DW$LOOP
       RET
;
;
;
HELLO$MSG:      DB      CR,LF,'Pgen Version 1.0',CR,LF,EOM
GET$MSG:        DB      CR,LF,'Get Booter?(y/n)',eom
READ$MSG:       DB      CR,LF,'Reading Booter from drive A, type return ',eom
PUT$MSG:        DB      CR,LF,LF,'Put Booter?(y/n)',eom
WRITE$MSG:      DB      CR,LF,'Writing Booter to drive A, type return ',eom
AGAIN$MSG:      DB      CR,LF,'Again?(y/n)',eom
REBOOT$MSG:     DB      CR,LF,LF,'Rebooting CP/M, type return ',eom
;
;
       DS      256
STACK   EQU     $
;
;
;
       END     TPA