home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug082.ark / SDNSGEN.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  10.6 KB  |  380 lines

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