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 / CPMUG001.ARK / RELOC.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  10KB  |  450 lines

  1. ; RELOC.ASM
  2. ;
  3. ;
  4. ; THIS IS A REGENERATED SOURCE TEXT OF THE PROGRAM PORTION OF
  5. ; RELOC.COM.  IT GENERATES THE SAME CODE (EXACTLY) AS IS FOUND
  6. ; IN LOCATIONS 100-102 AND 12C-393 (HEX) OF RELOC.COM.  RELOC.COM
  7. ; ALSO CONTAINS A COPY OF CP/M, BEGINNING AT 900H, AND A
  8. ; RELOCATION TABLE, PRESENTLY BEGINNING AT 2100H.
  9. ;
  10. ;
  11.     ORG    100H
  12. ;
  13. ; LOCATIONS OF INFORMATION FROM COMMAND LINE, PUT IN DEFAULT BUFFERS
  14. ; BY CCP:
  15. ;
  16. NAME1    EQU    5DH    ;FIRST "FILENAME" (NO. OF K)
  17. NAME2    EQU    6DH    ;2ND "FILENAME" (BLANK OR *)
  18. ;
  19. ENTRY    EQU    5    ;LOCATION OF JUMP TO BDOS
  20. REBOOT    EQU    0    ;LOCATION TO JUMP TO FOR REBOOT
  21. SYSTEM    EQU    900H    ;WHERE RELOC'S COPY OF SYSTEM RESIDES
  22. SERIAL    EQU    1300H    ;START OF SERIAL NUMBER IN THAT SYSTEM
  23. SIZE    EQU    801H    ;WHERE LENGTH OF SYSTEM IS STORED
  24. ;
  25. ;
  26. CR    EQU    0DH
  27. LF    EQU    0AH
  28. ;
  29. ;
  30. ;
  31. ;
  32. FIRST:    JMP    START
  33. ;
  34. ;
  35. ;
  36. ;
  37.     ORG    012CH
  38. ;
  39. START:    LXI    SP,800H
  40. ;
  41. ;
  42.     LXI    D,NAME1
  43.     LDAX    D    ;GET FIRST CHAR. OF WHAT IS ASSUMED TO BE NO. OF K
  44.     CPI    ' '
  45.     JZ    UNSPEC    ;JUMP IF NO NUMBER TYPED IN COMMAND
  46.     CPI    '?'
  47.     JZ    UNSPEC    ;RECOGNIZE BLANK OR QUESTION MARK AS NO-NUMBER
  48. ;
  49. ;
  50. ; IF WE ARE HERE, THERE IS A DECIMAL NUMBER AT 5DH WAITING TO BE READ
  51. ;
  52.     LXI    H,0    ;H WILL CONTAIN THE VALUE OF THE NUMBER
  53. DIGIT:    LDAX    D    ;GET NEXT DIGIT (ASCII)
  54.     INX    D    ;INCREMENT DIGIT POINTER
  55.     CPI    ' '
  56.     JZ    TESTNO    ;FINISHED GETTING NUMBER IF BLANK OR NULL
  57.     ORA    A    ;TEST FOR NULL (0)
  58.     JZ    TESTNO
  59.     SUI    '0'    ;SUBTRACT ASCII 0; THIS CONVERTS DIGIT TO NUMBER
  60.     CPI    10    ;MAKE SURE IT WAS REALLY A DIGIT (0-9)
  61.     JNC    INVAL    ;JUMP IF NOT
  62.     DAD    H    ;DOUBLE ACCUMULATED VALUE
  63.     PUSH    H    ;SAVE RESULT
  64.     DAD    H    ;DOUBLE IT AGAIN
  65.     DAD    H    ;AND AGAIN
  66.     POP    B    ;NOW GET RESULT SAVE ABOVE AND ADD TO VALUE
  67.     DAD    B    ;WE HAVE NOW MULTIPLIED VALUE BY 10
  68.     MOV    C,A    ;NOW ADD TO IT THE VALUE OF THE NEW DIGIT
  69.     MVI    B,0
  70.     DAD    B
  71.     JMP    DIGIT    ;AND GO BACK FOR NEXT DIGIT
  72. ;
  73. ;
  74. TESTNO:    MOV    A,H    ;GET HIGH BYTE OF NUMBER OF K SPECIFIED
  75.     ORA    A    ;IF IT'S NOT ZERO, NUMBER WAS 256 OR BIGGER
  76.     JNZ    INVAL    ; AND THEREFORE NOT A VALID MEMORY SIZE
  77.     MOV    A,L    ;GET LOW BYTE
  78.     CPI    16    ;SYSTEM MUST BE AT LEAST 16K
  79.     JC    INVAL ; SO ERROR IF <16.
  80. ;
  81. ;
  82. ; NOW MULTIPY NO. OF K BY 1024 TO GET SPECIFIED MEMORY SIZE
  83. ;
  84.     MVI    L,0    ;L WAS SAVED IN A ABOVE
  85.     MOV    H,A    ;THIS MULTIPLIES BY 256
  86.     DAD    H    ;MULTIPLY BY 2
  87.     DAD    H    ;MULTIPLY BY 2 AGAIN
  88.     JMP    PUTK    ;GO TO NEXT SECTION WITH H=MEMORY SIZE IN BYTES
  89. ;
  90. ;
  91. INVAL:    LXI    D,INVMSG
  92.     CALL    MSG    ;OUTPUT "INVALID MEMORY SIZE" MESAGE TO CONSOLE
  93.     JMP    REBOOT    ;REBOOT SYSTEM
  94. ;
  95. ;
  96. INVMSG:    DB  CR,LF,'INVALID MEMORY SIZE$'
  97. ;
  98. ;
  99. ; COME HERE IF MEMORY SIZE WAS NOT SPECIFIED IN COMMAND LINE
  100. ;
  101. UNSPEC:    LXI    H,0    ;SET UP TO FIND MEMORY SIZE
  102. PAGE:    INR    H    ;POINT TO 1ST LOCATION OF NEXT PAGE
  103.     JZ    FOUND    ;GET OUT OF LOOP IF WE FOUND 256 PAGES OF MEMORY (WHY?)
  104.     MOV    A,M    ;GET 1ST BYTE OF PAGE POINTED TO BY H
  105.     CMA        ;COMPLEMENT IT
  106.     MOV    M,A    ; AND PUT IT BACK
  107.     CMP    M    ;NOW READ BACK AND COMPARE
  108.     CMA        ;RESTORE MEMORY BEFORE JUMPING
  109.     MOV    M,A
  110.     JZ    PAGE    ;KEEP LOOPING IF MEMORY VALID
  111. FOUND:    MOV    A,H    ;L IS STILL ZERO, SO HL IS NUMBER OF BYTES OF MEMORY,
  112.     ANI    0FCH    ; TRUNCATED TO NEAREST 256. NOW ZERO BITS 0,1 OF H TO
  113.     MOV    H,A    ; TRUNCATE TO A MULTIPLE OF 1024
  114. PUTK:    PUSH    H    ;SAVE TRUNCATED MEMORY SIZE ON STACK
  115. ;
  116.     LHLD    ENTRY+1    ;GET STARTING ADDRESS OF PRESENT BDOS FROM THE JUMP AT LOC. 5
  117.     SHLD    BDOS    ;SAVE IT FOR LATER USE
  118. ;
  119.     POP    H    ;GET MEMORY SIZE AGAIN
  120.     PUSH    H    ; BUT LEAVE IT ON STACK TOP
  121.     MOV    A,H    ;TAKE NUMBER OF PAGES AND DIVIDE BY 4 (INTEGER)
  122.     RRC        ;TO GET NUMBER OF K.
  123.     RRC
  124.     ANI    3FH
  125.     MOV    B,A    ;SAVE NUMBER OF K IN B
  126.     LXI    H,CPMMSG+15 ;POINT TO OF NUMBER OF K (ASCII) IN "CONSTRUCTING" MESSAGE TEXT
  127.     MVI    A,'0'    ;SET IT TO ASCII 00
  128.     MOV    M,A
  129.     INX    H
  130.     MOV    M,A
  131. CNVRT1:    LXI    H,CPMMSG+16 ;LOOP TO CONVERT NO. OF K TO DECIMAL ASCII (2 DIGITS)
  132.     INR    M    ;INCREMENT LOW DIGIT
  133.     MOV    A,M    ;GET ITS NEW VALUE
  134.     CPI    '9'+1
  135.     JC    CNV1A    ;CONTINUE LOOP IF STILL IN THE RANGE '0' TO '9'
  136.     MVI    M,'0'    ;ELSE SET IT TO ASCII 0 AND INCREMENT HIGH DIGIT.
  137.     DCX    H
  138.     INR    M
  139. CNV1A:    DCR    B    ;DECREMENT REMAINDER OF NUMBER BEING CONVERTED
  140.     JNZ    CNVRT1    ; AND CONTINUE IN LOOP IF NOT YET ZERO
  141. ;
  142. ;
  143.     LXI    D,CPMMSG 
  144.     CALL    MSG    ;OUTPUT "CONSTRUCTING . . ." MESSAGE TO CONSOLE
  145. ;
  146. ;
  147.     LXI    H,SIZE    ;GET LENGTH OF SYSTEM IN BYTES
  148.     MOV    C,M
  149.     INX    H
  150.     MOV    B,M
  151.     PUSH    B    ;SAVE LENGTH IN B AND ON STACK
  152. ;
  153. ;
  154. ; SEARCH RELOC'S COPY OF THE SYSTEM FOR THE STRING "K CP/M VERS 1.3". THE
  155. ; SEARCH PRESENTLY BEGINS AT 900H AND CONTINUES THROUGH 900+LENGTH
  156. ;
  157. ;
  158.     LXI    H,SYSTEM
  159. SEARCH:    LXI    D,CPMMSG+17
  160.     MOV    A,B
  161.     ORA    C
  162.     JZ    NOFIND    ;EXIT IF SEARCH COMPLETED WITHOUT FINDING STRING
  163.     DCX    B    ;DECREMENT SEARCH COUNT AND SAVE ON STACK
  164.     PUSH    B
  165.     ;
  166.     MVI    C,15    ;SET STRING LENGTH FOR COMPARE LOOP
  167.     PUSH    H    ;SAVE CURRENTLY SEARCH ADDRESS ON STACK
  168. COMPR:    LDAX    D    ;LOOP TO COMPARE STRINGS- D POINTS TO ONE, H TO THE OTHER
  169.     CMP    M
  170.     JNZ    NEWLOC    ;GO TRY NEXT MEMORY POSITION IF COMPARISON FAILED
  171.     INX    D
  172.     INX    H
  173.     DCR    C
  174.     JZ    GOTIT
  175.     JMP    COMPR
  176. ;
  177. ;
  178. ;
  179. ;
  180. ;
  181.     DB    1
  182. SYNERR:    XRA    A
  183. SYNE1:    DCR    A
  184.     JNZ    SYNE1
  185.     LXI    H,76F3H
  186.     SHLD    BDOS    ;PUT "DI,HLT" AT BDOS, WHERE "CALL ENTRY" WILL RETURN
  187.     LXI    H,SYSCAL
  188.     MVI    M,0CDH    ;CHANGE INSTRUCTION AT SYSCAL FROM "JMP" TO "CALL"
  189.     LXI    D,SYNMSG-5
  190.     LXI    H,5
  191.     DAD    D
  192.     XCHG        ;THIS GETS "SYNC. ERROR" MESSAGE ADDRESS IN D
  193.     JMP    MSG    ;OUTPUT MESSAGE AND THEN HANG.
  194. ;
  195. ;
  196. ;
  197. ;
  198. NEWLOC: POP    H    ;GET SEARCH POINTER AGAIN
  199.     INX    H    ;INCREMENT IT
  200.     POP    B    ;RESTORE  REMAINING SEARCH COUNT
  201.     JMP    SEARCH    ;GO BACK TO LOOK FOR STRING AGAIN
  202. ;
  203. ;
  204. GOTIT:    POP    H    ;STRING FOUND- GET ITS LOCATION
  205.     POP    B    ;CLEAN UP STACK
  206.     DCX    H    ;POINT TO 2ND DIGIT OF NUMBER OF K IN STRING
  207.     LXI    D,CPMMSG+16
  208.     LDAX    D    ;GET ASCII NUMBER OF K FROM STRING, AND PUT IT INTO STRING JUST FOUND
  209.     MOV    M,A
  210.     DCX    H
  211.     DCX    D
  212.     LDAX    D
  213.     MOV    M,A
  214. ;
  215. ;
  216. ;
  217. ;
  218. NOFIND:    LXI    B,BDOS    ;GET LOW BYTE OF CURRENT BDOS ADDRESS
  219.     LDAX    B
  220.     CPI    6    ;THIS BYTE IS NORMALLY 06, BUT IS CHANGED BY DDT AND RESTORED ON RETURN TO SYSTEM
  221.     MVI    A,0
  222.     JNZ    SYNC1    ;GIVE SYNCHRONIZATION ERROR IF BYTE IS NOT 06
  223.     STAX    B    ;SET LOW BYTE OF BDOS ADDRESS TO ZERO, SO ADDRESS IS THAT OF SERIAL NUMBER
  224. ;
  225. ;
  226. ;
  227. ;
  228.     POP    B    ;GET SYSTEM LENGTH
  229.     POP    H    ;GET MEMORY SIZE IN BYTES
  230.     MOV    A,L    ;SUBTRACT B FROM H TO GET MSIZE-LENGTH
  231.     SUB    C    ; THIS IS ADDRESS NEW SYSTEM WILL RUN FROM
  232.     MOV    L,A
  233.     MOV    A,H
  234.     SBB    B
  235.     MOV    H,A
  236.     SHLD    NEWSYS    ;SAVE THIS ADDRESS AT NEWSYS AND IN D
  237.     XCHG
  238. ;
  239. ;
  240. ;
  241. ;
  242.     LXI    H,SYSTEM    ;POINT TO BEGINNING OF SYSTEM LOADED WITH RELOC.COM
  243.     PUSH    B    ;SAVE LENGTH
  244. ;
  245.     LDA    NAME2    ;GET 2ND ITEM IN COMMAND LINE
  246.     CPI    ' '    ;IF BLANK, SYSTEM IS TO BE PLACED AT ITS EXECUTION ADDRESS
  247.     JZ    EXEC
  248.     DAD    B    ;SET H TO POINT TO FIRST LOC. AFTER SYSTEM (START OF RELOCATION TABLE)
  249.     JMP    REL1
  250. ;
  251. ;
  252. ;
  253. ;
  254. SYNC1:    LXI    H,SYNERR ;SET JUMP AT SYNC2 TO GO TO SYNERR
  255.     SHLD    SYNC2+1
  256.     JMP    SYNC2
  257. ;
  258. ;
  259. ;
  260. ;
  261. ; IF 2ND ITEM IN COMMAND WAS BLANK, THEN COME HERE TO MOVE A COPY
  262. ; OF THE SYSTEM FROM 900 TO ITS EVENTUAL EXECUTION ADDRESS.
  263. ;
  264. ;
  265. EXEC:    MOV    A,B
  266.     ORA    C
  267.     JZ    REL1
  268.     DCX    B
  269.     MOV    A,M
  270.     STAX    D
  271.     INX    D
  272.     INX    H
  273.     JMP    EXEC
  274. ;
  275. ;
  276. ;
  277. ;
  278. ; LOOP TO PERFORM THE RELOCATION.
  279. ; MSIZE-LENGTH+100H IS ADDED TO EACH ADDRESS 
  280. ; MARKED BY A '1' IN THE RELOCATION BIT TABLE.
  281. ;
  282. ;
  283. REL1:    POP    B    ;GET LENGTH
  284.     PUSH    H    ;SAVE TABLE ADDRESS
  285.     LHLD    NEWSYS
  286.     XCHG        ;ADDRESS OF NEW SYSTEM IN D
  287.     LXI    H,100H
  288.     DAD    D    ;H IS NOW NEWSYS+100H
  289. ;
  290. ;
  291.     LDA    NAME2    ;GET 2ND COMMAND ITEM AGAIN
  292.     CPI    ' '
  293.     JZ    REL2
  294.     LXI    D,SYSTEM    ;IF NOT A SPACE, SET D TO PUT NEW SYSTEM IN PLACE FOR SYSGEN
  295. REL2:    MOV    A,B
  296.     ORA    C
  297.     JZ    FINISH    ;JUMP IF COUNT HAS REACHED ZERO
  298.     JMP    REL3
  299. ;
  300. ;
  301. SYNMSG:    DB  CR,LF,'SYNCRONIZATION ERROR$'
  302. ;
  303. ;
  304. REL3:    DCX    B    ;DECREMENT BYTE COUNT
  305.     MOV    A,E    ;GET LOW BYTE OF CURRENT ADDRESS IN NEW SYSTEM
  306.     ANI    7    ;IF IT IS A MULTIPLE OF 8, WE NEED TO GET ANOTHER
  307.     JNZ    REL4    ; BYTE OF THE RELOCATION TABLE
  308.     XTHL        ;GET H=CURRENT ADDRESS IN TABLE
  309.     MOV    A,M    ;GET THE BYTE THERE
  310.     INX    H    ;INCREMENT TABLE ADDRESS
  311.     XTHL        ;PUT IT BACK ON STACK
  312.     MOV    L,A
  313. REL4:    MOV    A,L    ;TEST NEXT BIT OF CURRENT TABLE BYTE
  314.     RAL
  315.     MOV    L,A
  316.     JNC    REL5    ;IF NOT SET, CONTINUE IN LOOP
  317.     LDAX    D    ;GET HIGH BYTE OF ADDRESS AT CURRENT LOCATION IN NEW SYSTEM
  318.     ADD    H    ;ADD HIGH BYTE OF  100H+EXECUTION ADDRESS
  319.     STAX    D    ; AND PUT BACK IN NEW SYSTEM
  320.     JMP    REL5
  321. REL5:    INX    D    ;POINT TO NEXT BYTE OF NEW SYSTEM
  322.     JMP    REL2
  323. ;
  324. ;
  325. ;
  326. ;
  327. FINISH: POP    D    ;CLEAN UP STACK
  328. ;
  329. ;
  330. ; COMPARE SERIAL NUMBER OF NEW SYSTEM WITH THAT OF SYSTEM CURRENTLY RUNNING.
  331. ;
  332. ;
  333.     LXI    D,SERIAL ;ADDRESS OF SERIAL NUMBER IN RELOC.COM
  334.     LHLD    BDOS    ;ADDRESS OF SERIAL NO. IN CURRENT SYSTEM
  335.     MVI    C,6    ;LOOP COUNT
  336. SERLP:    LDAX    D
  337.     CMP    M
  338.     JNZ    SYNC1
  339.     INX    H
  340.     INX    D
  341.     DCR    C
  342.     JNZ    SERLP
  343. ;
  344. ;
  345. ; IF SYSTEM WAS PUT AT EXECUTION ADDRESS, GO THERE
  346. ;
  347.     LDA    NAME2
  348.     CPI    ' '
  349.     JZ    SYSGO
  350. ;
  351. ;
  352. ; IF 900-97F IS ALL ZEROES, THEN MOVE THE WHOLE SYSTEM DOWN 80H BYTES
  353. ; FROM 980 TO 900
  354. ;
  355. ;
  356.     MVI    B,80H
  357.     LXI    H,SYSTEM
  358. TEST1:    MOV    A,M
  359.     ORA    A
  360.     JNZ    NOMOVE
  361.     INX    H
  362.     DCR    B
  363.     JNZ    TEST1
  364. ;
  365.     XCHG        ;D IS 980H
  366.     LHLD    SIZE    ;GET SYSTEM LENGTH
  367.     LXI    B,-80H
  368.     DAD    B
  369.     MOV    B,H
  370.     MOV    C,L    ;BC = LENGTH-128
  371.     LXI    H,900H
  372. MOVE:    MOV    A,B
  373.     ORA    C
  374.     JZ    NOMOVE
  375.     DCX    B
  376.     LDAX    D
  377.     MOV    M,A
  378.     INX    D
  379.     INX    H
  380.     JMP    MOVE
  381. ;
  382. ;
  383.     DB    1
  384. SYNC2:    JMP    SYNC2
  385. ;
  386. ;
  387. NOMOVE: LXI    H,SIZE
  388.     MOV    C,M
  389.     INX    H
  390.     MOV    B,M    ;B = LENGTH
  391.     LXI    H,900H
  392.     DAD    B
  393.     MOV    B,H    ;C IS ALREADY ZERO- NOW B IS NUMBER OF PAGES IN NEW SYSTEM
  394. ;
  395. ;
  396. ; PUT NUMBER OF PAGES IN THE NEW SYSTEM INTO THE "SAVE NN . . ." MESSAGE TEXT
  397. ;
  398.     LXI    H,ENDMSG+31
  399.     MVI    A,30H
  400.     MOV    M,A
  401.     INX    H
  402.     MOV    M,A
  403. PUTN:    DCR    B
  404.     JZ    PUTK2
  405.     LXI    H,ENDMSG+32
  406.     INR    M
  407.     MOV    A,M
  408.     CPI    '9'+1
  409.     JC    PUTN
  410.     MVI    M,30H
  411.     DCX    H
  412.     INR    M
  413.     JMP    PUTN
  414. ;
  415. ;
  416. PUTK2:    LHLD    CPMMSG+15
  417.     SHLD    ENDMSG+37    ;PUT NO. OF K IN MESSAGE
  418.     LXI    D,ENDMSG
  419.     CALL    MSG    ;OUTPUT MESSAGE TO CONSOLE
  420.     JMP    REBOOT    ;RETURN TO CP/M
  421. ;
  422. ;
  423. ;
  424. ;
  425. ENDMSG:    DB  CR,LF,'READY FOR "SYSGEN" OR',CR,LF
  426.     DB  '"SAVE 00 CPM00.COM"$'
  427. ;
  428. ;
  429. ;
  430. ;
  431. SYSGO:    LXI    D,1600H
  432.     LHLD    NEWSYS
  433.     DAD    D
  434.     PCHL        ;JUMP TO NEW SYSTEM
  435. ;
  436. ;
  437. ;
  438. ;
  439. MSG:    MVI    C,9
  440. SYSCAL:    JMP    ENTRY
  441. BDOS    DW    0
  442. NEWSYS    DW    0
  443. ;
  444. CPMMSG:    DB  CR,LF,'CONSTRUCTING 00K CP/M VERS 1.3$'
  445. ;
  446. ;
  447. ;
  448. ;
  449.     END
  450.