;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; GENESYS version 3.2 - July 18, 1981 ; r. l. plouffe ; for use with cp/m 1.45, 2.0x, or 2.2x ; on north star with lifeboat bios ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; This is a version of SYSGEN that runs above the ; sysgen image of cp/m, thus permitting the first four ; north star sectors to contain code for an expanded user ; area. To use this feature, the cold boot loader must ; be modified to load code from ccp-900H. This version of ; GENESYS patches in a complete new cold boot loader that ; accomplishes this function into the sysgen image prior to ; writing to either a CPM.xx file or to the system tracks. ; The new loader reads all 10 sectors of the system tracks ; except that it skips sector 4 on track 1 since that sector ; is read in by the boot prom. The init routine which you put ; in user1 should run at ccp-900H and move the user2 code ; to a location just above the running cp/m. A special org ; must be contained at the portion of init that runs at ; ccp-900h so that the lifeboat format byte will be present ; at 05CH above ccp-900H since that code will be resident ; at sector 0, track 1 of the north star disk where it is ; tested by the lifeboat bios for reading or writing of files ; so that the skew factor will be correct. GENEUSER.ASM which ; is also on this disk will do all of the above and provides ; general user code for 1.45, 2.0 and 2.2 including t102 clock, ; pmmi modem, and north star parity error routines as well. ; The program reads the format of the destination ; drive and changes the format byte found on the source ; drive so that the destination drive format remains ; unchanged after being written to with the 'sysgened' cp/m. ; Thus neither drive is changed in format so far as files ; are concerned after using GENESYS. ; ; BDOS EQU 0005H ;jmp to bdos function calls BIOSV EQU 0001H ;bios warm boot vector CR EQU 0DH ;carriage return LF EQU 0AH ;line feed TAB EQU 09H ;tab function BELL EQU 07H ;ding ; FCB EQU 005CH ;address of FCB FRSTCHAR EQU 005DH ;addr of 1rst char in FCB CURREC EQU 007CH ;addr of curr record # SYSIMG EQU 0100H ;cp/m sysgen image SEC0IMG EQU 0080H ;sector 0 image DMAINCR EQU 0080H ;dma increment amount ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Routine for moving the whole program beginning with START ; to just above the 'sysgen' image of cp/m so that the space ; from 100H to 8FFH will be available for init and user2 code ; for storage on sectors 0-3 of track 1 on the north star disk. ; If any code after START is added/changed, the address labels ; must be followed by EQU $+BIAS. ; DEST EQU 2D00H ;running location of genesys ; ORG SYSIMG ; LXI B,PEND1-SOURCE1 LXI H,DEST2+PEND1-SOURCE1 LXI D,SOURCE2+PEND1-SOURCE1-1 CALL MOVEIT LXI B,PEND-START ;# of bytes to move LXI H,DEST+PEND-START ;end of moved code LXI D,SOURCE-START+PEND-1 ;end of source code CALL MOVEIT PCHL ; MOVEIT: LDAX D ;get byte DCX H ;bump pointers MOV M,A ;new home DCX D DCX B ;bump byte count MOV A,B ;check if zero ORA C JNZ MOVEIT ;if not, keep moving RET ;jump to start ; SOURCE EQU $ ;boundary memory marker ; BIAS EQU DEST-SOURCE ;relocation amount ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; The beginning of it all. ; ; START: EQU $+BIAS ; LXI SP,STACK ;point to new stack LXI D,SIGNON ;give signon message CALL PRNMSG ;to the console CALL SKWGEN ;write the skew table LDA FRSTCHAR CPI 20H JZ NOFILE ; LXI D,FCB CALL OPEN ; INR A JNZ OPENOK ; LXI D,NOFILMSG ;say no source file CALL PRNMSG ;to the console JMP EXIT ; ; OPENOK: EQU $+BIAS ; XRA A STA CURREC MVI C,50H ;# of cp/m sectors in file ; CHKFIL: EQU $+BIAS ;this loop checks for bad file PUSH B LXI D,FCB CALL SEQRD ;read sequential ORA A POP B JNZ BADFILE ;if 0, say incomplete DCR C JNZ CHKFIL ;if not done, get another sec. ; initialize current record buffer and set dma to sys image XRA A STA CURREC ;set current record to 0 LXI H,SYSIMG ;initial dma ; now read all sectors of the file to ram at sys image RDFILE: EQU $+BIAS ; PUSH H MOV B,H ;set dma address MOV C,L CALL DMASET LXI D,FCB CALL SEQRD ;read sequential to dma POP H ORA A JNZ IMGRDY ; LXI D,DMAINCR DAD D JMP RDFILE ; ; BADFILE:EQU $+BIAS ; LXI D,INCMPMSG ;say source file incomplete CALL PRNMSG ;to the console JMP EXIT ; ; if no file in command line, get sys from selected drive NOFILE: EQU $+BIAS ; LXI D,SRCNAME ;ask for source drive name CALL PRNMSG ;at the console CALL CONIN ;read the console buffer SUI 41H CPI 4 JC FROM ; CALL BADNAME ; JMP NOFILE ; ; FROM: EQU $+BIAS ; STA CURRDRV ; ADI 41H ;convert to alpha STA SRCDRV ; LXI D,SRCMSG ;say to place source disk CALL PRNMSG ;to the console CALL CONIN ; CPI 0DH JNZ EXIT ; CALL CRLF ; XRA A STA RDWRFLG ;set flag to read CALL RDWRSYS ; ; IMGRDY: EQU $+BIAS ; LDA 900H ;get hi byte of cold loader org SUI 34H ;get the difference MOV C,A ;store in C for a while LXI H,CLDBTABL ;point to addresses of bytes in ;cold loader that need to be changed CHNGCLDBT:EQU $+BIAS MOV E,M INX H MOV D,M MOV A,M ORA E JZ MOVER LDAX D ADD C STAX D INX H JMP CHNGCLDBT ; now patch the cold boot loader into the system image ; DEST1 EQU 0907H ; MOVER: EQU $+BIAS LXI B,PEND1-SOURCE1 LXI H,DEST1+PEND1-SOURCE1 LXI D,PEND1-1 MOVCONT:EQU $+BIAS LDAX D DCX H MOV M,A DCX D DCX B MOV A,B ORA C JNZ MOVCONT ;now test and patch for bugs in the various versions LDA 1201H ;get version LHLD 900H-1 ;get hi byte of cldbt addr. MVI L,0CH ;addr in cldbt page to patch CPI 20H ;see if 2.0x JNZ TST22 ;if not, see if it's 2.2 SHLD 26BFH ;replace in patch table TST22: EQU $+BIAS CPI 22H ;see if 2.2 JNZ TST14 ;if not, see if it's 1.4 LDA 1511H ; CPI 01H ;see if it's 2.21A JZ TST14 ;if so, don't patch CPI 0CCH ;see if it's 2.22 JZ SKP221 SHLD 151BH ;replace in patch table ORA A ;clear status TST14: EQU $+BIAS CZ FIX221A ;fix if 221A SKP221: EQU $+BIAS MOV A,H ;get hi byte of cldbt addr. ADI 24H ;make it hi byte of sys size MOV B,A ;save for a while LDA 1201H ;get version CPI 0EH ;see if 1.45 JNZ RSTCNT ;if not jmp to reset counter MOV A,B ;get hi byte of sys size SUI 0AH ;make it hi byte of bios last blk MOV H,A ;put in H MVI L,0F7H ;addr in bios last pg to patch SHLD 1E6CH ;put in bdos patch table XRA A ;zero A STA 0906H ;patch coldboot loader MOV A,B ;get hi byte of sys size again SUI 0CH ;to make compatible w/1.45 sizing MOV B,A ;save in B ; now calculate the system size and store in SAVE prompt RSTCNT: EQU $+BIAS LXI H,3030H ;set to say 00 SHLD FILNAM+3 ;tens digit SYSSIZ: EQU $+BIAS LXI H,FILNAM+4 ;units digit INR M ;increment it MOV A,M ;to acc. CPI 3AH ;overflow of units? JC SYSSIZ1 ; MVI M,30H ;reset units digit DCX H ;go to tens digit INR M ;increment it SYSSIZ1:EQU $+BIAS DCR B DCR B DCR B DCR B JNZ SYSSIZ ;count more if not done ; now patch the image for cp/m version LDA 900H ;get the msb of booter MOV B,A ;store in B for a while LDA 1201H ;get the cp/m version # CPI 0EH ;see if version 1.45 LXI D,ONEFOUR ;point to image addresses JZ PATCHER ;if so jump to patch routine CPI 20H ;see if version 2.0x LXI D,TWOZERO ;point to image addresses JZ PATCHER ;if so jump to patch routine CPI 22H ;see if version 2.2x LXI D,TWOTWO ;point to image addresses JZ PATCHER ;if so jump to patch routine JMP BADVERS ;if none of the above,say sorry PATCHER:EQU $+BIAS LXI H,INIT+7-BIAS1+100H ;get patch location in booter CALL PATCH ;patch it LXI H,BOOT+9-BIAS1+100H CALL PATCH LXI H,BOOT+6-BIAS1+100H CALL PATCH LXI D,IMG0100 ;say cp/m image ready CALL PRNMSG ;to the console ; now put the sys image to a selected drive DESTDR: EQU $+BIAS ; LXI D,TODRV ;ask for destination drive name CALL PRNMSG ;at the console CALL CONIN ;read the console buffer CPI 0DH ;done? JZ EXIT ; SUI 41H CPI 4 JC DESTDRV ; CALL BADNAME ; JMP DESTDR ; ; FIX221A:EQU $+BIAS MOV A,H ;get hi byte of cldbt addr MVI L,0F2H ;byte to fix SHLD 153DH ;add to patch table XRA A ;A=0 STA 247AH ;remove stack unbalance so that ;read-after-write bit can be set ;in the MODE byte. otherwise, bug RET ; PATCH: EQU $+BIAS LDAX D ;lsb MOV M,A ;patch it INX H INX D LDAX D ;msb ADD B ;add hi byte of booter SUI 09H ;convert to hi byte of addr MOV M,A ;patch it INX D RET ; DESTDRV:EQU $+BIAS ; STA CURRDRV ; ADI 41H STA DSTDR ; ; read the first sector (with 10 retries) of dest drive ; and get format byte to store in system image XRA A ;zero the retry count STA RETRY ;put in retry counter buff. X10TRY: EQU $+BIAS LDA CURRDRV ;get current drive no. MOV C,A ; CALL DSKSEL ;select the drive MVI C,0 CALL TRKSET ;set to track 0 LXI B,1 ; CALL SECSET ;set to sector 1 LXI B,SEC0IMG ;dma CALL DMASET ;set dma to SEC0IMG LDA RETRY ;get retry count CPI 0AH ;allow 10 of them JC REPEAT ;increment and read ERROR: EQU $+BIAS LXI D,PERMERR ;point to error msg CALL PRNSTR ;send it to console JMP EXIT ;back to cp/m ; REPEAT: EQU $+BIAS INR A ;bump retry counter STA RETRY ; CALL SECRD ;read first sector to 80h ORA A ;bad read? JNZ X10TRY ;if so, try again ; TINU: EQU $+BIAS ; now get the format byte from dest drive 1rst sector image LDA 00DCH ;get dest drive format ; put format byte in system image STA 015CH ;store it in the sys image LXI D,DESTMSG ;say to place dest disk CALL PRNMSG ;at the console CALL CONIN ; CPI 0DH ;return key? JZ WRSYS ; CPI 20H ;space bar? JZ WRFILE ;if so, write sys to a file JMP EXIT ;exit to cp/m if any other key ; WRSYS: EQU $+BIAS CALL CRLF ;send cr,lf to console LXI D,SYSMSG CALL PRNMSG LXI H,RDWRFLG ;point to rd/wr flag buffer MVI M,1 ;set it for write operations CALL RDWRSYS ; DONE: EQU $+BIAS LXI D,FDONE ;say function complete CALL PRNSTR ;to the console JMP DESTDR ;want another drive? ; BADVERS:EQU $+BIAS LXI D,SORRY CALL PRNSTR HLT ; EXIT: EQU $+BIAS ; MVI C,0 CALL DSKSEL ;select drive A CALL CRLF ;output a cr,lf sequence JMP 0 ;return to cp/m ; BADNAME:EQU $+BIAS ; LXI D,INVLDR ;say invalid drive name CALL PRNMSG ;to the console RET ; BADOPEN:EQU $+BIAS LXI D,NOOPEN ;say cant open the file CALL PRNMSG ;to the console JMP EXIT ;back to cp/m ; BADWR: EQU $+BIAS LXI D,WRBAD ;say bad write operation CALL PRNMSG JMP EXIT ; WRFILE: EQU $+BIAS CALL CRLF ; MVI B,14 LXI D,FILNAM LXI H,FRSTCHAR OVER: EQU $+BIAS LDAX D MOV M,A INX H INX D DCR B JNZ OVER XRA A STA FCB STA CURREC ; MVI C,SELDRV LDA CURRDRV MOV E,A CALL BDOS ; LXI D,FCB MVI C,FILDEL CALL BDOS LXI D,FCB MVI C,FILMAK CALL BDOS INR A JZ BADOPEN LXI D,FILMSG CALL PRNMSG LXI H,SYSIMG ;start of system image WRFIL: EQU $+BIAS PUSH H XCHG CALL BUFSET LXI D,FCB MVI C,WRSEQ CALL BDOS POP H ORA A JNZ BADWR ;say bad write LXI D,DMAINCR ;increment dma by 80h DAD D PUSH H MVI A,50H ;# of cp/m sectors LXI H,CURREC CMP M POP H JZ CLOSIT JMP WRFIL ; CLOSIT: EQU $+BIAS LXI D,FCB MVI C,CLOSFIL CALL BDOS INR A JNZ DONE ; BADCLOS:EQU $+BIAS LXI D,NOCLOSE CALL PRNMSG JMP EXIT ; SORRY: EQU $+BIAS DB CR,LF,TAB,'SORRY, BAD' DB ' VERSION OF CP/M',BELL,'$' ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Routines for selecting drive, track, sector and setting of ; disk memory access address when reading or writing sys trks. ; Module provides for up to 10 tries at read or write ; and gives an error message if errors are detected. ; RDWRSYS:EQU $+BIAS ; ; select which drive LDA CURRDRV ;get current disk number MOV C,A CALL DSKSEL ;select disk ; initialize dma address LXI H,SYSIMG ;start of cp/m image SHLD IMGADR ;current image addr buffer ; initialize current track buffer MVI A,0FFH ;track zero-1 STA TRKBUF ;current track buffer ; initialize skew pointer to first entry in skew table LXI H,SKWTBL ;point to skew table SHLD SKWPTR ;put in skew pointer buffer ; now set the track number ; TRAKSET:EQU $+BIAS ; LXI H,TRKBUF ;get previous track # INR M ;advance track # MVI A,2 ;get # of system tracks CMP M ;see if done RZ ;if so, return LXI H,TRKBUF ;get track number MOV C,M CALL TRKSET ;set track number ; ; initialize sector number to zero XRA A ;zero the accumulator STA SECBUF ;sector number buffer ; now set sector and dma in accordance with skew table SCTRSET:EQU $+BIAS ; MVI A,28H ;get # of sectors/track LXI H,SECBUF ;get current sector number CMP M ;see if done JZ ADJDMA ; INR M ;advance sector number LDA TRKBUF ;get current track # ORA A JNZ SCTR ; LDA SECBUF ;get sector # MOV E,A MVI D,0 LHLD SKWPTR ;get skew pointer DCX H DAD D MOV A,M CPI 1H JC SCTRSET ; SCTR: EQU $+BIAS ; LXI H,SECBUF ;point to sector # buffer MOV E,M ;store sector # in DE pair MVI D,0 LHLD SKWPTR ;get skew pointer MOV B,M DCX H DAD D MOV C,M PUSH B CALL SECSET ;set sector POP B MOV A,C SUB B CALL X128 ; XCHG LHLD IMGADR ;get current image address DAD D MOV B,H MOV C,L CALL DMASET ;set dma address ; ; set read/write retry counter to zero XRA A STA RETRY ;set re-try counter to 0 ; now read or write up to 10 times until no error is detected TRYX10: EQU $+BIAS ; LDA RETRY ;get re-try count CPI 0AH ;allow 10 of them JC RDWRTRY ; LXI D,PERMERR ;say permanent error CALL PRNSTR ;to the console CALL CONIN ; CPI 0DH JNZ EXIT ; CALL CRLF ; JMP SCTRSET ; RDWRTRY:EQU $+BIAS ; INR A STA RETRY ;bump re-try counter LDA RDWRFLG ;see if read or write ORA A JZ READIT ;if zero, then read CALL SECWR ;write sector JMP ERRCHK ; ; READIT: EQU $+BIAS ; CALL SECRD ; ; ERRCHK: EQU $+BIAS ; ORA A JZ SCTRSET ;if zero, then do another sec JMP TRYX10 ;else try again ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; This routine multiplies sector number by 128 to adjust the ; current dma address. ; ADJDMA: EQU $+BIAS MVI A,28H ;get # of sectors/track CALL X128 ;multiply by 128 XCHG LHLD IMGADR ;get current image sddr DAD D ;adjust it SHLD IMGADR ;store it JMP TRAKSET X128: EQU $+BIAS ; MOV L,A MVI H,0 DAD H DAD H DAD H DAD H DAD H DAD H DAD H RET ; SKWGEN: EQU $+BIAS LXI H,SKWTBL MVI A,15H ; SKWGEN1:EQU $+BIAS SUI 14H CALL FOURSEC ADI 10H CALL FOURSEC CPI 29H JNZ SKWGEN1 RET ; FOURSEC:EQU $+BIAS MVI C,4 SKWWR: EQU $+BIAS MOV M,A INX H INR A DCR C JNZ SKWWR RET ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Routines for msg out to console. ; CRLF: EQU $+BIAS ;get carriage ret, line feed LXI D,CRLFMSG ;point to it JMP PRNSTR ;send it to console ; CRLFMSG:EQU $+BIAS ;carriage ret, line feed DB CR,LF,'$' ; PRNMSG: EQU $+BIAS ; PUSH D CALL CRLF ;get carriage ret, line feed POP D ; fall through to prnstr ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; BDOS and BIOS functions ; PRNSTR: EQU $+BIAS ; MVI C,PRTSTRG ;print string to console JMP BDOS ; DSKSEL: EQU $+BIAS ; LHLD BIOSV LXI D,SELDSK ;select disk drive DAD D PCHL ; TRKSET: EQU $+BIAS ; PUSH B MVI B,0 ;zero the B register CALL TRKSET1 ;set track number POP B RET ; TRKSET1:EQU $+BIAS ; LHLD BIOSV LXI D,SETTRK ;set track number DAD D PCHL ; SECSET: EQU $+BIAS ; LHLD BIOSV LXI D,SETSEC ;set sector number DAD D PCHL ; DMASET: EQU $+BIAS LHLD BIOSV LXI D,SETDMA ;set disk memory address DAD D PCHL ; SECRD: EQU $+BIAS ; LHLD BIOSV LXI D,RDSEC ;read selected sector DAD D PCHL ; SECWR: EQU $+BIAS ; LHLD BIOSV LXI D,WRSEC ;write selected sector DAD D PCHL ; SEQRD: EQU $+BIAS ; MVI C,RDSEQ ;read next 128 bytes to dma JMP BDOS ; BUFSET: EQU $+BIAS MVI C,SETBUF ;set the dma JMP BDOS ; OPEN: EQU $+BIAS ; MVI C,OPNFIL ;open the file JMP BDOS ; CONIN: EQU $+BIAS MVI C,CONSIN ;console input CALL BDOS CPI 60H ;convert to upper case RC CPI 7BH RNC ANI 5FH RET ; ; Messages for the console ; SIGNON: EQU $+BIAS ; DB TAB,'GENESYS vers 3.2',CR,LF DB TAB,'for cp/m 1.45,2.01,2.2,2.21A or 2.22',CR,LF DB TAB,'on North Star DQ w/Lifeboat bios' DB CR,LF,TAB,'July 18, 1981',CR,LF,'$' ; SRCNAME:EQU $+BIAS ; DB TAB,'Source drive NAME: $' ; SRCMSG: EQU $+BIAS ; DB TAB,'Put SOURCE disk on: ' ; SRCDRV: EQU $+BIAS ; DB 0,', & hit RETURN$' ; IMG0100:EQU $+BIAS ; DB CR,LF,TAB,'CP/M image in RAM from 100H' DB ' to 2900H$' ; TODRV: EQU $+BIAS ; DB CR,LF,TAB,'Destination drive NAME' DB CR,LF,TAB,'(or RETURN to reboot): $' ; DESTMSG:EQU $+BIAS ; DB TAB,'Put DESTINATION disk on: ' ; DSTDR: EQU $+BIAS ; DB 0,CR,LF,CR,LF,TAB,'& hit RETURN to write' DB ' system' DB CR,LF,TAB,'or, hit SPACE bar to save ' ; FILNAM: EQU $+BIAS DB 'CPMxx COM',0,0,0,'$' ; PERMERR:EQU $+BIAS ; DB TAB,'Hard ERROR',BELL,'$' ; FDONE: EQU $+BIAS ; DB TAB,'Done',BELL,'$' ; INVLDR: EQU $+BIAS ; DB TAB,'Invalid, (Use A B C or D)$' ; NOFILMSG:EQU $+BIAS ; DB TAB,'No source file$' ; INCMPMSG:EQU $+BIAS ; DB TAB,'Source file incomplete$' ; NOOPEN: EQU $+BIAS DB TAB,'Can`t open file$' ; WRBAD EQU $+BIAS DB TAB,'Bad write -full disk?$' ; NOCLOSE:EQU $+BIAS DB TAB,'Can`t close file -write protected?$' ; SYSMSG: EQU $+BIAS DB TAB,'Writing cp/m system -wait-$' ; FILMSG EQU $+BIAS DB TAB,'Writing cp/m.com file -wait-$' ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Tables ; CLDBTABL:EQU $+BIAS DW STRT-1 DW STRT+3 DW STRT+7 DW STRT+0AH DW TWOTRKS+7 DW TWOTRKS+0DH DW STSECT+2 DW STSECT+0BH DW STSECT+0EH DW RDENBL+5 DW DELAY+3 DW DELAY+8 DW SYNCH+4 DW SYNCH+8 DW COUNT+6 DW COUNT+0FH DW COUNT+12H DW HALT+2 DW READSECS+2 DW TWOBLKS+8 DW TWOBLKS+0DH DW TWOBLKS+12H DW NEXTSEC+9 DW NEXTSEC+0DH DW NEXTSEC+11H DW NEXTSEC+20H DW NEXTSEC+24H DW INIT+2 DW CHNGBIOS+7 DW CHNGBIOS+0EH DW BOOT+2 DW ADVSEC+2 DW ADVSEC+8 DW DETSEC+4 DW DETSEC+8 DW DETSEC+0EH DW 0000H ;table scan terminator ; ONEFOUR:EQU $+BIAS ;table for version 1.45 DW 1E40H ;promtabl DW 1F00H ;bios DW 090CH ;promhi ; TWOZERO:EQU $+BIAS ;table for version 2.0x DW 26B5H ;promtabl DW 2000H ;bios DW 26F5H ;promhi ; TWOTWO: EQU $+BIAS ;table for version 2.2x DW 1511H ;promtabl DW 2000H ;bios DW 26F5H ;promhi ; PEND EQU $+BIAS DS DEST2-PEND ; ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Bdos function call equates ; CONSIN EQU 01H ;console input RDSEQ EQU 14H ;read sequential WRSEQ EQU 15H ;write sequential SELDRV EQU 0EH ;select disk SETBUF EQU 1AH ;set dma OPNFIL EQU 0FH ;open file FILDEL EQU 13H ;delete file FILMAK EQU 16H ;make a file CLOSFIL EQU 10H ;close file PRTSTRG EQU 09H ;print string to console ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Bios function call equates ; SELDSK EQU 18H ;select disk drive SETTRK EQU 1BH ;set track number SETSEC EQU 1EH ;set sector number SETDMA EQU 21H ;set disk memory address RDSEC EQU 24H ;read selected sector WRSEC EQU 27H ;write selected sector ; ;============================================================= ; ; COLDBOOT LOADER FOR NORTH STAR ; ; WILL LOAD ALL SECTORS ON BOTH SYSTEM TRACKS TO RAM BEGINNING ; AT CCP-900H THUS GIVING A SECOND USER AREA OF UP TO 2KBYTES. ; THE SOFTWARE SKIPS READING OF SECTOR 4 ON TRACK 1 SINCE THAT ; SECTOR IS LOADED BY THE BOOTSTRAP PROM ON THE DISK CONTROLLER. ; ; R. L. PLOUFFE ; 12/19/80 ; ;============================================================= ; ORIG EQU 0807H ; PROM EQU 0E800H ;DISK CONTR PROM ADDRESS ;DO NOT CHANGE EVEN IF YOU HAVE ;RELOCATED YOUR PROM. THE COLD BOOT ;LOADER NEEDS THIS VALUE TO DETERMINE ;AMOUNT BY WHICH YOU HAVE MOVED YOUR ;PROM AND THEN PATCH ALL PROM DEPENDENT ;BYTES IN THE BIOS BY ADDING THE DIFF- ;ERENCE. USER2 EQU ORIG-800H-7H ;LOCATION OF 2ND USER AREA CMDMSB EQU (PROM+300H)/256 ;HI BYTE OF CONTROLLER COMMANDS DSKRD EQU 40H ;BYTE FOR READ COMMAND ASTAT EQU 10H ;LO BYTE FOR A STATUS MASK RSTSEC EQU 11H ;LO BYTE FOR RESET SECTOR COMMAND STEPIN EQU 21H ;LO BYTE FOR STEP-IN CMD, DR 1 STEPIN1 EQU 31H ;LSB FOR STEPIN,DR1,HEAD LOADED CMOTON EQU 35H ;MOTORS ON, GET C-STATUS RESET EQU 07H ;RESET CONTROLLER, DESELECT DRIVES ;AND STOP THE MOTORS DMA EQU USER2 ;BEGINNING RAM ADDRESS STACK1 EQU USER2 ;STACK ; DEST2 EQU DEST+707H ORG ORIG SOURCE2 EQU $ BIAS1 EQU DEST2-SOURCE2 SOURCE1 EQU $+BIAS1 ; JMP INIT STRT: EQU $+BIAS1 DI LXI SP,STACK1+BIAS1 XCHG SHLD RDCMD LXI H,DMA+BIAS1 MVI E,2 TWOTRKS0:EQU $+BIAS1 LXI B,0A00H TWOTRKS:EQU $+BIAS1 PUSH H PUSH B PUSH D MOV A,E DCR A JZ READ MOV A,C CPI 4 JZ NEXTSEC READ: EQU $+BIAS1 PUSH H STSECT: EQU $+BIAS1 CALL ONESEC MVI L,CMOTON MOV A,M ANI 0FH CMP C JNZ STSECT LHLD RDCMD MVI L,ASTAT RDENBL: EQU $+BIAS1 MOV A,M ANI 4 JZ RDENBL MVI A,9 DELAY: EQU $+BIAS1 DCR A JNZ DELAY MVI B,8CH LHLD RDCMD MVI L,ASTAT SYNCH: EQU $+BIAS1 MOV A,M RRC JC READSECS DCR B JNZ SYNCH ; REBOOT: EQU $+BIAS1 LXI H,0FFFFH COUNT: EQU $+BIAS1 INX H MOV A,M CPI 76H JZ COUNT MVI A,76H MOV M,A MOV A,L CPI 07H JZ HALT LHLD RDCMD DCR H DCR H DCR H MVI L,0 PCHL ; HALT: EQU $+BIAS1 LHLD RDCMD MVI L,RESET ;RESET THE DISK CONTROLLER MOV A,M ;DO IT HLT ;STOP THE COMPUTER ; READSECS:EQU $+BIAS1 LHLD RDCMD XCHG POP H MVI B,0 MVI L,0 MVI C,2 TWOBLKS:EQU $+BIAS1 LDAX D MOV M,A XRA B RLC MOV B,A INR L JNZ TWOBLKS INR H DCR C JNZ TWOBLKS LDAX D XRA B JNZ REBOOT NEXTSEC:EQU $+BIAS1 POP D POP B POP H INR H INR H INR C DCR B JNZ TWOTRKS DCR E JZ INIT PUSH H LHLD RDCMD DCR H MVI L,STEPIN MOV A,M MVI L,STEPIN1 MOV A,M MVI L,STEPIN MOV A,M MVI D,2 CALL ADVSEC POP H JMP TWOTRKS0 ; INIT: EQU $+BIAS1 LDA CMDHI SUI CMDMSB MOV C,A LXI H,0000H ;0000H, storage location for ;PROMTABL address CHNGBIOS:EQU $+BIAS1 MOV E,M INX H MOV D,M MOV A,M ORA E JZ BOOT LDAX D ADD C STAX D INX H JMP CHNGBIOS ; ; ONESEC: EQU $+BIAS1 MVI D,1 ADVSEC: EQU $+BIAS1 LHLD RDCMD MVI L,RSTSEC MOV A,M LHLD RDCMD MVI L,ASTAT DETSEC: EQU $+BIAS1 MOV A,M ORA A JP DETSEC DCR D LHLD RDCMD MVI L,RSTSEC MOV A,M JNZ ADVSEC RET ; DUPL: EQU $+BIAS1 DW 0EB40H ;duplicate required here for 2.21A ;gets patched to correct prom by the ;patch table in bdos ; BOOT: EQU $+BIAS1 LDA CMDHI SUI 3 STA 0000H ;0000H, storage location for ;addr of PROM hi byte JMP 0000H ;storage loc. for jmp to BIOS ; RDCMD: EQU $+BIAS1 DB DSKRD CMDHI: EQU $+BIAS1 DB CMDMSB ; PEND1 EQU $+BIAS1 ; ;========================================================== ; ; Buffer space ; SKWTBL: EQU $+BIAS1 DS 40 ;written by SKWGEN ; CURRDRV:EQU $+BIAS1 ;current disk # buffer DS 1 ; TRKBUF: EQU $+BIAS1 ;current track buffer DS 1 ; SECBUF: EQU $+BIAS1 ;sector number buffer DS 1 ; RDWRFLG:EQU $+BIAS1 ;read/write flag WRITE=1 DS 1 ; IMGADR: EQU $+BIAS1 ;current image address DS 2 ; RETRY: EQU $+BIAS1 ;buffer for re-try count DS 1 ; SKWPTR: EQU $+BIAS1 ;skew pointer buffer DS 2 ; DS 207 ;stack area STACK: EQU $+BIAS1 ; ; the END