home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG082.ARK / NSGEN.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  11KB  |  375 lines

  1.     TITLE    'NSGEN V3.4 - WRITE CP/M 2.2 TO NORTH STAR DISK'
  2. ;    PAGE    44
  3. ;
  4. ; These routines copyright (c) 1980, 1981, 1982 by Steve Bogolub,
  5. ; 2338 S. Scoville Ave., Berwyn, IL 60402. This software may be
  6. ; used freely for non-commercial purposes only, and may not be sold.
  7. ;
  8. ;************************************************************
  9. ;
  10. ;  THIS PROGRAM IS SET UP TO PROVIDE THE FUNCTIONS
  11. ; OF THE DIGITAL RESEARCH STANDARD CP/M PROGRAM
  12. ; 'SYSGEN', BUT FOR A NORTH STAR DOUBLE DENSITY
  13. ; VERSION OF CP/M. SINCE THE NORTH STAR HAS 10
  14. ; SECTORS PER TRACK, WITH 512 BYTES PER SECTOR
  15. ; USING DOUBLE DENSITY, THE STANDARD SYSGEN PROGRAM
  16. ; IS WORTHLESS. USING THIS VERSION, THE CCP AND
  17. ; BDOS ARE WRITTEN OUT TO CONSECTIVE SECTORS OF
  18. ; TRACK ONE, 0-9 INCLUSIVE. ELEVEN 512-BYTE
  19. ; SECTORS ARE REQUIRED, SO THE LAST ONE IS
  20. ; WRITTEN OUT TO TRACK ZERO, SECTOR THREE. THE
  21. ; CCP/BDOS CODE IS ASSUMED TO BE LOADED INTO
  22. ; CONTIGUOUS MEMORY LOCATIONS STARTING AT 0980H.
  23. ; THE CONTROL CODE FOR THE JADE DOUBLE D FLOPPY
  24. ; DISK CONTROLLER IS EXPECTED AT ADDRESS 1F80H,
  25. ; EXTENDING FOR 1024 BYTES. THIS CODE IS WRITTEN
  26. ; OUT TO TRACK ZERO, SECTORS ONE AND TWO. THE
  27. ; NORTH STAR BIOS IS ASSUMED TO RESIDE IN MEMORY
  28. ; FROM 2380H TO 2F7FH INCLUSIVE. THE LAST 512 BYTES
  29. ; OF BIOS (2D80H - 2F7FH) PERFORM THE FUNCTION
  30. ; OF DISK BOOT, AND ARE WRITTEN OUT TO TRACK ZERO,
  31. ; SECTOR FOUR, WHERE THE NORTH STAR PROM BOOT
  32. ; EXPECTS TO FIND THE SYSTEM BOOT CODE. THE REST
  33. ; OF BIOS (1ST 3K, 2380H - 2D7FH) IS WRITTEN OUT
  34. ; TO TRACK ZERO, SECTORS 5-9 INCLUSIVE. TRACK
  35. ; ZERO, SECTOR ZERO IS RESERVED FOR A LIFEBOAT-
  36. ; COMPATIBLE ID AND FUTURE ADDITIONS.
  37. ;
  38. ;  IN ORDER TO FIND THE RIGHT SECTORS, WE ASSUME
  39. ; THAT THERE ARE 40 LOGICAL SECTORS PER TRACK,
  40. ; NUMBERED 1-40 INCLUSIVE. IN ORDER TO WRITE AT
  41. ; HIGH SPEED, WE ASSUME THAT THERE ARE 4 LOGICAL
  42. ; SECTORS PER PHYSICAL SECTOR, AND LOAD THE C-REG
  43. ; WITH THE APPROPRIATE DEBLOCKING FLAG BEFORE
  44. ; CALLING BIOS TO WRITE A SECTOR. IN ADDITION,
  45. ; WE READ OR WRITE EVERY 3RD NORTH STAR SECTOR.
  46. ;
  47.     ORG    0100H        ;ORG TO TPA
  48. ;
  49. ;  BDOS EQUATES
  50. ;
  51. BDOS    EQU    0005H        ;BDOS ENTRY ADDRESS
  52. CONIN    EQU    1        ;CONSOLE INPUT
  53. CONOUT    EQU    2        ;CONSOLE OUTPUT
  54. ;
  55. CR    EQU    0DH        ;ASCII CR
  56. LF    EQU    0AH        ;ASCII LF
  57. ;
  58. ;  BIOS OFFSET EQUATES
  59. ;
  60. WARMB    EQU    0000H        ;BIOS WARM BOOT VECTOR
  61. BIOS    EQU    WARMB+1     ;PTR TO BIOS VECTOR TABLE
  62. ;
  63. SELDSK    EQU    1BH-3        ;SELECT DISK DRIVE
  64. SETTRK    EQU    SELDSK+3    ;SET TRACK NUMBER
  65. SETSEC    EQU    SETTRK+3    ;SET SECTOR NUMBER
  66. SETDMA    EQU    SETSEC+3    ;SET DMA ADDRESS
  67. READ    EQU    SETDMA+3    ;READ SELECTED SECTOR
  68. WRITE    EQU    READ+3        ;WRITE SELECTED SECTOR
  69. ;
  70. NDRVS    EQU    2        ;# OF DRIVES WE CAN USE
  71.                 ;(ONLY A: AND B: ARE N*)
  72. ;
  73. ;  CP/M IMAGE ADDRESS (WHERE CCP LEFT BY MOVCPM)
  74. ;
  75. CPMIA    EQU    0980H
  76. ;
  77. ;  PROGRAM START. SET UP STACK PTR AND GET SOURCE DISK.
  78. ;
  79. NSGEN:    LXI    SP,NSGEN    ;SET STACK PTR
  80.     LXI    H,HELLO     ;PRINT OUT SIGNON
  81.     CALL    MSGOT
  82. ;
  83. GETSRC: LXI    H,SRCMSG    ;ASK FOR SOURCE DISK LETTER
  84.     CALL    MSGOT
  85.     CALL    CHARIN        ;GET SINGLE CHAR FOLDED
  86.     CPI    CR        ;IS ANSWER <RET>?
  87.     JZ    GETDST        ;SKIP SOURCE GET IF SO
  88.     STA    SRCLET        ;SAVE LETTER IF NOT
  89.     SUI    'A'        ;MAP TO BINARY VALUE FROM 0
  90.     CPI    NDRVS        ;MAKE SURE NOT TOO BIG
  91.     JC    SRCOK        ;PASS IF OK
  92.     LXI    H,BADNAM    ;FLAG ERROR IF NOT
  93.     CALL    MSGOT
  94.     JMP    GETSRC        ; AND TRY AGAIN
  95. ;
  96. SRCOK:    CALL    BSEL        ;CALL BIOS TO SELECT DISK
  97.     LXI    H,SRCON     ;PROMPT FOR SOURCE DISK
  98.     CALL    MSGOT
  99.     CALL    CHARIN        ;WAIT FOR <RET>
  100.     CPI    CR
  101.     JNZ    REBOOT        ;REBOOT IF ANYTHING ELSE TYPED
  102. ;
  103. ;  READ THE SYSTEM FROM THE SPECIFIED DRIVE
  104. ;
  105.     XRA    A        ;IF OK, FLAG DISK READ OPS
  106.     STA    DFLAG
  107.     CALL    XFRSYS        ;READ SYSTEM INTO MEMORY
  108.     JNZ    GETSRC        ;IF ABORTED, TRY AGAIN
  109.     LXI    H,FNCDUN    ;FUNCTION DONE
  110.     CALL    MSGOT
  111. ;
  112. ;  GET THE DESTINATION DISK
  113. ;
  114. GETDST: LXI    H,DSTMSG    ;GET DESTINATION NAME
  115.     CALL    MSGOT
  116.     CALL    CHARIN
  117.     CPI    CR        ;SEE IF DONE
  118.     JZ    REBOOT        ;GET OUT IF SO
  119.     STA    DSTLET        ;IF NOT, SAVE DEST LETTER
  120.     SUI    'A'        ;MAKE SURE IN RANGE
  121.     CPI    NDRVS
  122.     JC    DSTOK        ;PASS IF SO
  123.     LXI    H,BADNAM    ;FLAG BAD NAME IF NOT
  124.     CALL    MSGOT
  125.     JMP    GETDST        ; THEN ASK AGAIN
  126. ;
  127. DSTOK:    CALL    BSEL        ;CALL BIOS TO SELECT DISK
  128.     LXI    H,DSTON     ;PROMPT FOR SOURCE DISK
  129.     CALL    MSGOT
  130.     CALL    CHARIN        ;WAIT FOR <RET>
  131.     CPI    CR
  132.     JNZ    REBOOT        ;REBOOT IF ANYTHING ELSE TYPED
  133. ;
  134. ;  WRITE TO THE DESTINATION DISK
  135. ;
  136.     MVI    A,1        ;FLAG DISK WRITE
  137.     STA    DFLAG
  138.     CALL    XFRSYS        ;WRITE OUT SYSTEM
  139.     JNZ    GETDST        ;NO MSG IF ABORTED
  140.     LXI    H,FNCDUN    ;INDICATE DONE
  141.     CALL    MSGOT
  142.     JMP    GETDST        ;ASK ABOUT WRITING AGAIN
  143. ;
  144. ;  HERE WHEN DONE TO SELECT DRIVE A AND REBOOT
  145. ;
  146. REBOOT: XRA    A        ;SELECT DRIVE A
  147.     CALL    BSEL
  148.     JMP    WARMB        ; THEN REBOOT CP/M
  149. ;
  150. ;  SUBROUTINE XFRSYS TRANSFERS THE SYSTEM IMAGE FROM
  151. ; OR TO THE SELECTED DISK, BASED ON THE CONTENTS OF
  152. ; 'DFLAG'. IF 'DFLAG' CONTAINS ZERO, THE SYSTEM IS
  153. ; READ IN. IF 'DFLAG' CONTAINS ONE, THE SYSTEM IS
  154. ; WRITTEN OUT. BIOS DISK READ AND WRITE ARE CALLED
  155. ; DIRECTLY TO DO I/O. IF AN ERROR IS RETURNED FROM
  156. ; BIOS, IT IS REPORTED TO THE OPERATOR, WHO IS GIVEN
  157. ; THE OPTION OF IGNORING THE ERROR, OR ABORTING THE
  158. ; XFER. IF THE XFER WAS ABORTED, WE RETURN NON-ZERO
  159. ; IN ACC. BECAUSE THE HOST BUFFER CONTENTS ARE
  160. ; SCRAPPED ON I/O ERROR, WE CANNOT RETRY THE I/O.
  161. ; BESIDES, THE BIOS HAS ALREADY RETRIED IT FOR US.
  162. ;
  163. XFRSYS: MVI    A,MAXSEC    ;GET # OF CP/M SECTORS TO XFER
  164.     STA    SCOUNT        ; AND SET COUNT TO DO
  165.     LXI    H,SECTBL    ;PT TO SECTOR TABLE
  166.     SHLD    SECPTR        ;INIT THE SECTOR ADDRESS PTR
  167. ;
  168. ;  GET NEXT SECTOR ADDRESS FROM TABLE, AND SET BIOS PTRS
  169. ;
  170. NXTSEC: LHLD    SECPTR        ;GET NEXT SECTOR ADDRESS
  171.     MOV    A,M        ; INTO ACC
  172.     RLC            ;BRING TRACK BIT INTO POSITION
  173.     ANI    1        ;TRACK IS ZERO OR ONE
  174.     MOV    C,A        ;PUT TRK # IN C FOR BIOS
  175.     CALL    BTRK        ;CALL BIOS TO SET TRACK #
  176.     LHLD    SECPTR        ;GET SECTOR ADDRESS AGAIN
  177.     MOV    A,M
  178.     ANI    7FH        ;STRIP TRACK BIT
  179.     MOV    C,A        ;GET INTO CORRECT REG
  180.     INX    H        ;BOP SECTOR TABLE PTR
  181.     SHLD    SECPTR        ; AND UPDATE
  182.     CALL    BSEC        ;CALL BIOS TO SET SECTOR #
  183.     LHLD    SECPTR        ;GET TABLE PTR AGAIN
  184.     MOV    A,M        ;GET LOGICAL SECTOR #
  185.     RRC            ;CALC MEM OFFSET HIGH BYTE
  186.     ANI    7FH
  187.     MOV    B,A        ;PUT FINAL VALUE IN BC
  188.     MOV    A,M        ;NOW CALC LOW BYTE
  189.     RRC
  190.     ANI    80H
  191.     MOV    C,A
  192.     INX    H        ;BOP PTR AGAIN
  193.     SHLD    SECPTR
  194.     LXI    H,CPMIA     ;CALC MEM ADDR
  195.     DAD    B
  196.     MOV    B,H        ;NEED IT IN BC
  197.     MOV    C,L
  198.     CALL    BDMA        ;CALL BIOS TO SET DMA ADDR
  199. ;
  200. ;  TIME TO DO THE SECTOR READ OR WRITE. CHECK DFLAG TO DECIDE.
  201. ;
  202. DOIO:    LDA    DFLAG        ;ARE WE READING OR WRITING?
  203.     ORA    A        ;IF ZERO, READING
  204.     JNZ    WRTSEC        ;BRANCH IF WRITING
  205.     CALL    BREAD        ;IF READING, CALL BIOS TO DO IT
  206.     JMP    CHKSEC        ;NOW GO CHECK FOR ERRORS
  207. ;
  208. WRTSEC: CALL    BWRITE        ;CALL BIOS TO WRITE SECTOR
  209. ;
  210. CHKSEC: ORA    A        ;ERROR IF BIOS RETURNS NON-ZERO
  211.     JZ    XFROK        ;PASS IF I/O OK
  212. ;
  213. ;  I/O ERROR. ASK OPERATOR FOR A RULING.
  214. ;
  215. IOERR:    LXI    H,IOEMSG    ;REPORT ERROR, AND ASK
  216.     CALL    MSGOT        ; WHAT ACTION TO TAKE
  217.     CALL    CHARIN        ;GET REPLY
  218.     CPI    'I'        ;IGNORE THE ERROR?
  219.     JZ    XFROK        ;GO ON IF SO
  220.     SUI    'A'        ;ABORT THE XFER?
  221.     JNZ    IOERR        ;ASK AGAIN IF NEITHER OF THE ABOVE
  222.     INR    A        ;IF ABORT,
  223.     RET            ; RETURN NON-ZERO TO CALLER
  224. ;
  225. ;  COUNT OFF LAST SECTOR TO SEE IF DONE
  226. ;
  227. XFROK:    LDA    SCOUNT
  228.     DCR    A        ;COUNT OFF LAST SECTOR
  229.     STA    SCOUNT
  230.     JNZ    NXTSEC        ;IF MORE TO DO, GO BACK
  231.     RET            ; ELSE RET ZERO TO CALLER
  232. ;
  233. ;
  234. ;  BIOS I/O ROUTINES -- DISK SELECT
  235. ;
  236. BSEL:    MOV    C,A        ;MOVE DISK # TO BIOS REG
  237.     LXI    D,SELDSK    ;SELECT DISK
  238.     JMP    GOBIOS
  239. ;
  240. ;  -- SET TRACK
  241. ;
  242. BTRK:    LXI    D,SETTRK    ;SET TRACK C
  243.     JMP    GOBIOS
  244. ;
  245. ;  -- SET SECTOR
  246. ;
  247. BSEC:    LXI    D,SETSEC    ;SET SECTOR C
  248.     JMP    GOBIOS
  249. ;
  250. ;  -- SET DMA ADDRESS
  251. ;
  252. BDMA:    LXI    D,SETDMA    ;SET DMA ADDR BC
  253.     JMP    GOBIOS
  254. ;
  255. ;  -- READ SECTOR
  256. ;
  257. BREAD:    LXI    D,READ        ;READ SETUP SECTOR
  258.     JMP    GOBIOS
  259. ;
  260. ;  -- WRITE SECTOR
  261. ;
  262. BWRITE: LXI    D,WRITE     ;WRITE SETUP SECTOR
  263. ;
  264. ;  SINCE WE KNOW THAT THE NORTH STAR I/O IS BEING
  265. ; DEBLOCKED, LOAD C-REG WITH A VALUE OF 2 TO PREVENT
  266. ; PRE-READ FOR EVERY SECTOR BUT THE LAST ONE. FOR THAT
  267. ; SECTOR, LOAD C-REG WITH A VALUE OF 1 TO FORCE A WRITE
  268. ; TO FLUSH THE BIOS DEBLOCKING BUFFER BEFORE WE LEAVE,
  269. ; OR A REBOOT MAY LOSE THE LAST PHYSICAL SECTOR WE
  270. ; WANTED TO WRITE OUT.
  271. ;
  272.     MVI    C,2        ;WRITE TO UNALLOCATED
  273.     LDA    SCOUNT        ;CHECK FOR WRITING TO
  274.     DCR    A        ; LAST SECTOR
  275.     JNZ    GOBIOS        ;JUMP IF NOT
  276.     DCR    C        ;FORCE WRITE IF LAST
  277. ;
  278. ;  XFER TO BIOS VIA VECTOR WHOSE OFFSET IS IN DE
  279. ;
  280. GOBIOS: LHLD    BIOS        ;PT TO BIOS WARM BOOT VECTOR
  281.     DAD    D        ;CALC DESIRED VECTOR ADDR
  282.     PCHL            ;GO THERE
  283. ;
  284. ;
  285. ;  OUTPUT MESSAGE PT'ED AT BY HL TO CONSOLE. MESSAGE
  286. ; IS A STRING OF CHARACTERS TERMINATED BY A ZERO BYTE.
  287. ;
  288. MSGOT:    MOV    A,M        ;GET NEXT BYTE
  289.     ORA    A
  290.     RZ            ;IF NULL, DONE
  291.     PUSH    H        ;IF NOT, SAVE PTR
  292.     MOV    E,A        ;CHAR TO BDOS REG
  293.     MVI    C,CONOUT    ;FUNCTION
  294.     CALL    BDOS        ;GO OUTPUT CHAR
  295.     POP    H        ;RESTORE PTR
  296.     INX    H        ;PT TO NEXT BYTE
  297.     JMP    MSGOT        ;GO BACK FOR MORE
  298. ;
  299. ;  CONSOLE INPUT CHAR FUNCTION. LOWER CASE IS FOLDED
  300. ; TO UPPER ON RETURN.
  301. ;
  302. CHARIN: MVI    C,CONIN     ;CONSOLE INPUT FUNCTION
  303.     CALL    BDOS        ;GET CHAR FROM CONSOLE
  304.     CPI    'A'+20H     ;FOLD LOWER CASE
  305.     RC
  306.     CPI    'Z'+20H+1
  307.     RNC
  308.     SUI    20H
  309.     RET
  310. ;
  311. ;  MESSAGES
  312. ;
  313. HELLO:    DB    'NSGEN V3.4',0
  314. SRCMSG: DB    CR,LF,'Enter source drive name (A-','A'+NDRVS-1
  315.     DB    ') or <ret> to skip: ',0
  316. DSTMSG: DB    CR,LF,'Enter destination drive name (A-'
  317.     DB    'A'+NDRVS-1,') or <ret> to reboot: ',0
  318. BADNAM: DB    CR,LF,'Invalid drive name.',0
  319. SRCON:    DB    CR,LF,'Source on '
  320. SRCLET: DB    ' :, then type <ret>: ',0
  321. DSTON:    DB    CR,LF,'Destination on '
  322. DSTLET: DB    ' :, then type <ret>: ',0
  323. FNCDUN: DB    CR,LF,'Function complete.',0
  324. IOEMSG: DB    CR,LF,'Disk I/O error. Type "I" to ignore or'
  325.     DB    ' "A" to abort transfer: ',0
  326. ;
  327. ;  SECTOR ADDRESS TABLE. EACH ENTRY CONSISTS
  328. ; OF TWO BYTES. THE FIRST BYTE REPRESENTS THE
  329. ; SECTOR'S DISK LOCATION. IF HIGH BIT IS SET,
  330. ; SECTOR IS ON TRACK ONE. IF NOT, SECTOR IS
  331. ; ON TRACK ZERO. LOW SEVEN BITS REPRESENT SECTOR
  332. ; NUMBER WITHIN TRACK. THE SECOND BYTE OF THE
  333. ; ENTRY IS THE LOGICAL SECTOR OFFSET FROM THE
  334. ; START OF THE CP/M IMAGE IN MEMORY, WHICH IS
  335. ; USED TO CALCULATE THE ACTUAL MEMORY ADDRESS
  336. ; OF THAT SECTOR SO THAT I/O CAN BE DONE.
  337. ;
  338. ;  MAXSEC REPRESENTS THE TOTAL NUMBER OF
  339. ; SECTORS IN THE TABLE. REASSEMBLE TO CHANGE
  340. ; THE NUMBER OF SECTORS INVOLVED IN A TRANSFER.
  341. ;
  342. SECTBL:             ;SECTOR TABLE
  343. ;
  344.                     ; NORTH STAR TRK, SEC
  345. ;
  346.     DB    01+80H,00,02+80H,01,03+80H,02,04+80H,03 ; 1,0
  347.     DB    13+80H,12,14+80H,13,15+80H,14,16+80H,15 ; 1,3
  348.     DB    25+80H,24,26+80H,25,27+80H,26,28+80H,27 ; 1,6
  349.     DB    37+80H,36,38+80H,37,39+80H,38,40+80H,39 ; 1,9
  350.     DB    09+80H,08,10+80H,09,11+80H,10,12+80H,11 ; 1,2
  351.     DB    21+80H,20,22+80H,21,23+80H,22,24+80H,23 ; 1,5
  352.     DB    33+80H,32,34+80H,33,35+80H,34,36+80H,35 ; 1,8
  353.     DB    05+80H,04,06+80H,05,07+80H,06,08+80H,07 ; 1,1
  354.     DB    17+80H,16,18+80H,17,19+80H,18,20+80H,19 ; 1,4
  355.     DB    29+80H,28,30+80H,29,31+80H,30,32+80H,31 ; 1,7
  356.     DB    13+00H,40,14+00H,41,15+00H,42,16+00H,43 ; 0,3
  357.     DB    25+00H,56,26+00H,57,27+00H,58,28+00H,59 ; 0,6
  358.     DB    37+00H,68,38+00H,69,39+00H,70,40+00H,71 ; 0,9
  359.     DB    09+00H,48,10+00H,49,11+00H,50,12+00H,51 ; 0,2
  360.     DB    21+00H,52,22+00H,53,23+00H,54,24+00H,55 ; 0,5
  361.     DB    33+00H,64,34+00H,65,35+00H,66,36+00H,67 ; 0,8
  362.     DB    05+00H,44,06+00H,45,07+00H,46,08+00H,47 ; 0,1
  363.     DB    17+00H,72,18+00H,73,19+00H,74,20+00H,75 ; 0,4
  364.     DB    29+00H,60,30+00H,61,31+00H,62,32+00H,63 ; 0,7
  365. ;
  366. MAXSEC    EQU    ($-SECTBL)/2    ;# OF SECTORS IN TABLE
  367. ;
  368. ;  VARIABLE DATA
  369. ;
  370. DFLAG:    DS    1        ;=0, READ SYS. =1, WRITE SYS.
  371. SECPTR: DS    2        ;PTR INTO SECTBL
  372. SCOUNT: DS    1        ;COUNT OF SECTORS LEFT TO XFER
  373. ;
  374.     END    NSGEN
  375.