Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

440 lines
9.3 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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