mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
440 lines
8.7 KiB
NASM
440 lines
8.7 KiB
NASM
TITLE 'SYSGEN - SYSTEM GENERATION PROGRAM 8/79'
|
|
; SYSTEM GENERATION PROGRAM, VERSION FOR MDS
|
|
VERS EQU 20 ;X.X
|
|
;
|
|
; COPYRIGHT (C) DIGITAL RESEARCH
|
|
; 1976, 1977, 1978, 1979
|
|
;
|
|
NSECTS EQU 26 ;NO. OF SECTORS PER TRACK
|
|
NTRKS EQU 2 ;NO. OF OPERATING SYSTEM TRACKS
|
|
NDISKS EQU 4 ;NUMBER OF DISK DRIVES
|
|
SECSIZ EQU 128 ;SIZE OF EACH SECTOR
|
|
LOG2SEC EQU 7 ;LOG 2 SECSIZ
|
|
SKEW EQU 1 ;SECTOR SKEW FACTOR
|
|
;
|
|
FCB EQU 005CH ;DEFAULT FCB LOCATION
|
|
FCBCR EQU FCB+32 ;CURRENT RECORD LOCATION
|
|
TPA EQU 0100H ;TRANSIENT PROGRAM AREA
|
|
LOADP EQU 900H ;LOAD POINT FOR SYSTEM DURING LOAD/STORE
|
|
BDOS EQU 5H ;DOS ENTRY POINT
|
|
BOOT EQU 0 ;JMP TO 'BOOT' TO REBOOT SYSTEM
|
|
CONI EQU 1 ;CONSOLE INPUT FUNCTION
|
|
CONO EQU 2 ;CONSOLE OUTPUT FUNCTION
|
|
SELF EQU 14 ;SELECT DISK
|
|
OPENF EQU 15 ;DISK OPEN FUNCTION
|
|
DREADF EQU 20 ;DISK READ FUNCTION
|
|
;
|
|
MAXTRY EQU 10 ;MAXIMUM NUMBER OF RETRIES ON EACH READ/WRITE
|
|
CR EQU 0DH ;CARRIAGE RETURN
|
|
LF EQU 0AH ;LINE FEED
|
|
STACKSIZE EQU 16 ;SIZE OF LOCAL STACK
|
|
;
|
|
WBOOT EQU 1 ;ADDRESS OF WARM BOOT (OTHER PATCH ENTRY
|
|
; POINTS ARE COMPUTED RELATIVE TO WBOOT)
|
|
SELDSK EQU 24 ;WBOOT+24 FOR DISK SELECT
|
|
SETTRK EQU 27 ;WBOOT+27 FOR SET TRACK FUNCTION
|
|
SETSEC EQU 30 ;WBOOT+30 FOR SET SECTOR FUNCTION
|
|
SETDMA EQU 33 ;WBOOT+33 FOR SET DMA ADDRESS
|
|
READF EQU 36 ;WBOOT+36 FOR READ FUNCTION
|
|
WRITF EQU 39 ;WBOOT+39 FOR WRITE FUNCTION
|
|
;
|
|
ORG TPA ;TRANSIENT PROGRAM AREA
|
|
JMP START
|
|
DB 'COPYRIGHT (C) 1978, DIGITAL RESEARCH '
|
|
;
|
|
; TRANSLATE TABLE - SECTOR NUMBERS ARE TRANSLATED
|
|
; HERE TO DECREASE THE SYSGEN TIME FOR MISSED SECTORS
|
|
; WHEN SLOW CONTROLLERS ARE INVOLVED. TRANSLATION TAKES
|
|
; PLACE ACCORDING TO THE "SKEW" FACTOR SET ABOVE.
|
|
;
|
|
OST: DB NTRKS ;OPERATING SYSTEM TRACKS
|
|
SPT: DB NSECTS ;SECTORS PER TRACK (CAN BE PATCHED)
|
|
TRAN: ;BASE OF TRANSLATE TABLE
|
|
TRELT SET 1 ;FIRST/NEXT TRAN ELEMENT
|
|
TRBASE SET 1 ;BASE FOR WRAPAROUND
|
|
REPT NSECTS ;ONCE FOR EACH SECTOR ON A TRACK
|
|
DB TRELT ;GENERATE FIRST/NEXT SECTOR
|
|
TRELT SET TRELT+SKEW
|
|
IF TRELT GT NSECTS
|
|
TRBASE SET TRBASE+1
|
|
TRELT SET TRBASE
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
; NOW LEAVE SPACE FOR EXTENSIONS TO TRANSLATE TABLE
|
|
IF NSECTS LT 64
|
|
REPT 64-NSECTS
|
|
DB 0
|
|
ENDM
|
|
;
|
|
;
|
|
;
|
|
;
|
|
; UTILITY SUBROUTINES
|
|
MULTSEC:
|
|
;MULTIPLY THE SECTOR NUMBER IN A BY THE SECTOR SIZE
|
|
MOV L,A! MVI H,0 ;SECTOR NUMBER IN HL
|
|
REPT LOG2SEC ;LOG 2 OF SECTOR SIZE
|
|
DAD H
|
|
ENDM
|
|
RET ;WITH HL = SECTOR * SECTOR SIZE
|
|
;
|
|
GETCHAR:
|
|
; READ CONSOLE CHARACTER TO REGISTER A
|
|
MVI C,CONI! CALL BDOS!
|
|
; CONVERT TO UPPER CASE BEFORE RETURN
|
|
CPI 'A' OR 20H ! RC ;RETURN IF BELOW LOWER CASE A
|
|
CPI ('Z' OR 20H) + 1
|
|
RNC ;RETURN IF ABOVE LOWER CASE Z
|
|
ANI 5FH! RET
|
|
;
|
|
PUTCHAR:
|
|
; WRITE CHARACTER FROM A TO CONSOLE
|
|
MOV E,A! MVI C,CONO! CALL BDOS! RET
|
|
;
|
|
CRLF: ;SEND CARRIAGE RETURN, LINE FEED
|
|
MVI A,CR
|
|
CALL PUTCHAR
|
|
MVI A,LF
|
|
CALL PUTCHAR
|
|
RET
|
|
;
|
|
CRMSG: ;PRINT MESSAGE ADDRESSED BY H,L TIL ZERO
|
|
;WITH LEADING CRLF
|
|
PUSH H! CALL CRLF! POP H ;DROP THRU TO OUTMSG0
|
|
OUTMSG:
|
|
MOV A,M! ORA A! RZ
|
|
; MESSAGE NOT YET COMPLETED
|
|
PUSH H! CALL PUTCHAR! POP H! INX H
|
|
JMP OUTMSG
|
|
;
|
|
SEL:
|
|
; SELECT DISK GIVEN BY REGISTER A
|
|
MOV C,A! LHLD WBOOT! LXI D,SELDSK! DAD D! PCHL
|
|
;
|
|
TRK: ;SET UP TRACK
|
|
LHLD WBOOT ;ADDRESS OF BOOT ENTRY
|
|
LXI D,SETTRK ;OFFSET FOR SETTRK ENTRY
|
|
DAD D
|
|
PCHL ;GONE TO SETTRK
|
|
;
|
|
SEC: ;SET UP SECTOR NUMBER
|
|
LHLD WBOOT
|
|
LXI D,SETSEC
|
|
DAD D
|
|
PCHL
|
|
;
|
|
DMA: ;SET DMA ADDRESS TO VALUE OF B,C
|
|
LHLD WBOOT
|
|
LXI D,SETDMA
|
|
DAD D
|
|
PCHL
|
|
;
|
|
READ: ;PERFORM READ OPERATION
|
|
LHLD WBOOT
|
|
LXI D,READF
|
|
DAD D
|
|
PCHL
|
|
;
|
|
WRITE: ;PERFORM WRITE OPERATON
|
|
LHLD WBOOT
|
|
LXI D,WRITF
|
|
DAD D
|
|
PCHL
|
|
;
|
|
DREAD: ;DISK READ FUNCTION
|
|
MVI C,DREADF
|
|
JMP BDOS
|
|
;
|
|
OPEN: ;FILE OPEN FUNCTION
|
|
MVI C,OPENF ! JMP BDOS
|
|
;
|
|
GETPUT:
|
|
; GET OR PUT CP/M (RW=0 FOR READ, 1 FOR WRITE)
|
|
; DISK IS ALREADY SELECTED
|
|
;
|
|
LXI H,LOADP ;LOAD POINT IN RAM FOR CP/M DURING SYSGEN
|
|
SHLD DMADDR
|
|
;
|
|
; CLEAR TRACK TO 00
|
|
MVI A,-1 ;START WITH TRACK EQUAL -1
|
|
STA TRACK
|
|
;
|
|
RWTRK: ;READ OR WRITE NEXT TRACK
|
|
LXI H,TRACK
|
|
INR M ;TRACK = TRACK + 1
|
|
LDA OST ;NUMBER OF OPERATING SYSTEM TRACKS
|
|
CMP M ;= TRACK NUMBER ?
|
|
JZ ENDRW ;END OF READ OR WRITE
|
|
;
|
|
; OTHERWISE NOTDONE, GO TO NEXT TRACK
|
|
MOV C,M ;TRACK NUMBER
|
|
CALL TRK ;TO SET TRACK
|
|
MVI A,-1 ;COUNTS 0, 1, 2, . . . 25
|
|
STA SECTOR ;SECTOR INCREMENTED BEFORE READ OR WRITE
|
|
;
|
|
RWSEC: ;READ OR WRITE SECTOR
|
|
LDA SPT ;SECTORS PER TRACK
|
|
LXI H,SECTOR
|
|
INR M ;TO NEXT SECTOR
|
|
CMP M ;A=26 AND M=0 1 2...25 (USUALLY)
|
|
JZ ENDTRK ;
|
|
;
|
|
; READ OR WRITE SECTOR TO OR FROM CURRENT DMA ADDR
|
|
LXI H,SECTOR
|
|
MOV E,M ;SECTOR NUMBER
|
|
MVI D,0 ;TO DE
|
|
LXI H,TRAN
|
|
MOV B,M ;TRAN(0) IN B
|
|
DAD D ;SECTOR TRANSLATED
|
|
MOV C,M ;VALUE TO C READY FOR SELECT
|
|
PUSH B ;SAVE TRAN(0),TRAN(SECTOR)
|
|
CALL SEC ;SET UP SECTOR NUMBER
|
|
POP B ;RECALL TRAN(0),TRAN(SECTOR)
|
|
MOV A,C ;TRAN(SECTOR)
|
|
SUB B ;-TRAN(0)
|
|
CALL MULTSEC ;*SECTOR SIZE
|
|
XCHG ;TO DE
|
|
LHLD DMADDR ;BASE DMA ADDRESS FOR THIS TRACK
|
|
DAD D ;+(TRAN(SECTOR)-TRAN(0))*SECSIZ
|
|
MOV B,H
|
|
MOV C,L ;TO BC FOR SEC CALL
|
|
CALL DMA ;DMA ADDRESS SET FROM B,C
|
|
; DMA ADDRESS SET, CLEAR RETRY COUNT
|
|
XRA A
|
|
STA RETRY ;SET TO ZERO RETRIES
|
|
;
|
|
TRYSEC: ;TRY TO READ OR WRITE CURRENT SECTOR
|
|
LDA RETRY
|
|
CPI MAXTRY ;TOO MANY RETRIES?
|
|
JC TRYOK
|
|
;
|
|
; PAST MAXTRIES, MESSAGE AND IGNORE
|
|
LXI H,ERRMSG
|
|
CALL OUTMSG
|
|
CALL GETCHAR
|
|
CPI CR
|
|
JNZ REBOOT
|
|
;
|
|
; TYPED A CR, OK TO IGNORE
|
|
CALL CRLF
|
|
JMP RWSEC
|
|
;
|
|
TRYOK:
|
|
; OK TO TRY READ OR WRITE
|
|
INR A
|
|
STA RETRY ;RETRY=RETRY+1
|
|
LDA RW ;READ OR WRITE?
|
|
ORA A
|
|
JZ TRYREAD
|
|
;
|
|
; MUST BE WRITE
|
|
CALL WRITE
|
|
JMP CHKRW ;CHECK FOR ERROR RETURNS
|
|
TRYREAD:
|
|
CALL READ
|
|
CHKRW:
|
|
ORA A
|
|
JZ RWSEC ;ZERO FLAG IF R/W OK
|
|
;
|
|
; ERROR, RETRY OPERATION
|
|
JMP TRYSEC
|
|
;
|
|
; END OF TRACK
|
|
ENDTRK:
|
|
LDA SPT ;SECTORS PER TRACK
|
|
CALL MULTSEC ;*SECSIZ
|
|
XCHG ;TO DE
|
|
LHLD DMADDR ;BASE DMA FOR THIS TRACK
|
|
DAD D ;+SPT*SECSIZ
|
|
SHLD DMADDR ;READY FOR NEXT TRACK
|
|
JMP RWTRK ;FOR ANOTHER TRACK
|
|
;
|
|
ENDRW: ;END OF READ OR WRITE, RETURN TO CALLER
|
|
RET
|
|
;
|
|
;
|
|
START:
|
|
;
|
|
LXI SP,STACK ;SET LOCAL STACK POINTER
|
|
LXI H,SIGNON
|
|
CALL OUTMSG
|
|
;
|
|
; CHECK FOR DEFAULT FILE LOAD INSTEAD OF GET
|
|
;
|
|
LDA FCB+1 ;BLANK IF NO FILE
|
|
CPI ' '
|
|
JZ GETSYS ;SKIP TO GET SYSTEM MESSAGE IF BLANK
|
|
LXI D,FCB ;TRY TO OPEN IT
|
|
CALL OPEN ;
|
|
INR A ;255 BECOMES 00
|
|
JNZ RDOK ;OK TO READ IF NOT 255
|
|
;
|
|
; FILE NOT PRESENT, ERROR AND REBOOT
|
|
;
|
|
LXI H,NOFILE
|
|
CALL CRMSG
|
|
JMP REBOOT
|
|
;
|
|
; FILE PRESENT
|
|
; READ TO LOAD POINT
|
|
;
|
|
RDOK:
|
|
XRA A
|
|
STA FCBCR ;CURRENT RECORD = 0
|
|
;
|
|
; PRE-READ AREA FROM TPA TO LOADP
|
|
;
|
|
MVI C,(LOADP-TPA)/SECSIZ
|
|
; PRE-READ FILE
|
|
PRERD:
|
|
PUSH B ;SAVE COUNT
|
|
LXI D,FCB ;INPUT FILE CONTROL COUNT
|
|
CALL DREAD ;ASSUME SET TO DEFAULT BUFFER
|
|
POP B ;RESTORE COUNT
|
|
ORA A
|
|
JNZ BADRD ;CANNOT ENCOUNTER END-OF FILE
|
|
DCR C ;COUNT DOWN
|
|
JNZ PRERD ;FOR ANOTHER SECTOR
|
|
;
|
|
; SECTORS SKIPPED AT BEGINNING OF FILE
|
|
;
|
|
LXI H,LOADP
|
|
RDINP:
|
|
PUSH H
|
|
MOV B,H
|
|
MOV C,L ;READY FOR DMA
|
|
CALL DMA ;DMA ADDRESS SET
|
|
LXI D,FCB ;READY FOR READ
|
|
CALL DREAD ;
|
|
POP H ;RECALL DMA ADDRESS
|
|
ORA A ;00 IF READ OK
|
|
JNZ PUTSYS ;ASSUME EOF IF NOT.
|
|
; MORE TO READ, CONTINUE
|
|
LXI D,SECSIZ
|
|
DAD D ;HL IS NEW LOAD ADDRESS
|
|
JMP RDINP
|
|
;
|
|
BADRD: ;EOF ENCOUNTERED IN INPUT FILE
|
|
|
|
LXI H,BADFILE
|
|
CALL CRMSG
|
|
JMP REBOOT
|
|
;
|
|
;
|
|
GETSYS:
|
|
LXI H,ASKGET ;GET SYSTEM?
|
|
CALL CRMSG
|
|
CALL GETCHAR
|
|
CPI CR
|
|
JZ PUTSYS ;SKIP IF CR ONLY
|
|
;
|
|
SUI 'A' ;NORMALIZE DRIVE NUMBER
|
|
CPI NDISKS ;VALID DRIVE?
|
|
JC GETC ;SKIP TO GETC IF SO
|
|
;
|
|
; INVALID DRIVE NUMBER
|
|
CALL BADDISK
|
|
JMP GETSYS ;TO TRY AGAIN
|
|
;
|
|
GETC:
|
|
; SELECT DISK GIVEN BY REGISTER A
|
|
ADI 'A'
|
|
STA GDISK ;TO SET MESSAGE
|
|
SUI 'A'
|
|
CALL SEL ;TO SELECT THE DRIVE
|
|
; GETSYS, SET RW TO READ AND GET THE SYSTEM
|
|
CALL CRLF
|
|
LXI H,GETMSG
|
|
CALL OUTMSG
|
|
CALL GETCHAR
|
|
CPI CR
|
|
JNZ REBOOT
|
|
CALL CRLF
|
|
;
|
|
XRA A
|
|
STA RW
|
|
CALL GETPUT
|
|
LXI H,DONE
|
|
CALL OUTMSG
|
|
;
|
|
; PUT SYSTEM
|
|
PUTSYS:
|
|
LXI H,ASKPUT
|
|
CALL CRMSG
|
|
CALL GETCHAR
|
|
CPI CR
|
|
JZ REBOOT
|
|
SUI 'A'
|
|
CPI NDISKS
|
|
JC PUTC
|
|
;
|
|
; INVALID DRIVE NAME
|
|
CALL BADDISK
|
|
JMP PUTSYS ;TO TRY AGAIN
|
|
;
|
|
PUTC:
|
|
; SET DISK FROM REGISTER C
|
|
ADI 'A'
|
|
STA PDISK ;MESSAGE SET
|
|
SUI 'A'
|
|
CALL SEL ;SELECT DEST DRIVE
|
|
; PUT SYSTEM, SET RW TO WRITE
|
|
LXI H,PUTMSG
|
|
CALL CRMSG
|
|
CALL GETCHAR
|
|
CPI CR
|
|
JNZ REBOOT
|
|
CALL CRLF
|
|
;
|
|
LXI H,RW
|
|
MVI M,1
|
|
CALL GETPUT ;TO PUT SYSTEM BACK ON DISKETTE
|
|
LXI H,DONE
|
|
CALL OUTMSG
|
|
JMP PUTSYS ;FOR ANOTHER PUT OPERATION
|
|
;
|
|
REBOOT:
|
|
MVI A,0
|
|
CALL SEL
|
|
CALL CRLF
|
|
JMP BOOT
|
|
BADDISK:
|
|
;BAD DISK NAME
|
|
LXI H,QDISK
|
|
CALL CRMSG
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
; DATA AREAS
|
|
; MESSAGES
|
|
SIGNON: DB 'SYSGEN VER '
|
|
DB VERS/10+'0','.',VERS MOD 10+'0'
|
|
DB 0
|
|
ASKGET: DB 'SOURCE DRIVE NAME (OR RETURN TO SKIP)',0
|
|
GETMSG: DB 'SOURCE ON '
|
|
GDISK: DS 1 ;FILLED IN AT GET FUNCTION
|
|
DB ', THEN TYPE RETURN',0
|
|
ASKPUT: DB 'DESTINATION DRIVE NAME (OR RETURN TO REBOOT)',0
|
|
PUTMSG: DB 'DESTINATION ON '
|
|
PDISK: DS 1 ;FILLED IN AT PUT FUNCTION
|
|
DB ', THEN TYPE RETURN',0
|
|
ERRMSG: DB 'PERMANENT ERROR, TYPE RETURN TO IGNORE',0
|
|
DONE: DB 'FUNCTION COMPLETE',0
|
|
QDISK: DB 'INVALID DRIVE NAME (USE A, B, C, OR D)',0
|
|
NOFILE: DB 'NO SOURCE FILE ON DISK',0
|
|
BADFILE:
|
|
DB 'SOURCE FILE INCOMPLETE',0
|
|
;
|
|
; VARIABLES
|
|
SDISK: DS 1 ;SELECTED DISK FOR CURRENT OPERATION
|
|
TRACK: DS 1 ;CURRENT TRACK
|
|
SECTOR: DS 1 ;CURRENT SECTOR
|
|
RW: DS 1 ;READ IF 0, WRITE IF 1
|
|
DMADDR: DS 2 ;CURRENT DMA ADDRESS
|
|
RETRY: DS 1 ;NUMBER OF TRIES ON THIS SECTOR
|
|
DS STACKSIZE*2
|
|
STACK:
|
|
END
|