home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / misc / smc203.ark / CALL.ASM < prev    next >
Encoding:
Assembly Source File  |  1983-07-28  |  6.6 KB  |  536 lines

  1.  
  2. ;
  3. ; CALL.A  Small-C version 2 arithmetic and logical library
  4. ;
  5. ;    (RMAC Version 05/10/88, Dave Johnson)
  6. ;    (ASM  Version 07/28/83, Bill Randle)
  7. ;
  8. LINK    EQU    1
  9. ;
  10.      IF    LINK
  11.     PUBLIC    CCDDGC
  12.     PUBLIC    CCDSGC
  13.     PUBLIC    CCGCHAR
  14.     PUBLIC    CCARGC
  15.     PUBLIC    CCSXT
  16.     PUBLIC    CCDDGI
  17.     PUBLIC    CCDSGI
  18.     PUBLIC    CCGINT
  19.     PUBLIC    CCDECC
  20.     PUBLIC    CCINCC
  21.     PUBLIC    CCPDPC
  22.     PUBLIC    CCPCHAR
  23.     PUBLIC    CCDECI
  24.     PUBLIC    CCINCI
  25.     PUBLIC    CCPDPI
  26.     PUBLIC    CCPINT
  27.     PUBLIC    CCOR
  28.     PUBLIC    CCXOR
  29.     PUBLIC    CCAND
  30.     PUBLIC    CCEQ
  31.     PUBLIC    CCNE
  32.     PUBLIC    CCGT
  33.     PUBLIC    CCLE
  34.     PUBLIC    CCGE
  35.     PUBLIC    CCLT
  36.     PUBLIC    CCUGE
  37.     PUBLIC    CCULT
  38.     PUBLIC    CCUGT
  39.     PUBLIC    CCULE
  40.     PUBLIC    CCASR
  41.     PUBLIC    CCASL
  42.     PUBLIC    CCSUB
  43.     PUBLIC    CCNEG
  44.     PUBLIC    CCCOM
  45.     PUBLIC    CCMULT
  46.     PUBLIC    CCDIV
  47.     PUBLIC    CCLNEG
  48.     PUBLIC    CCSWITCH
  49.      ENDIF
  50. ;
  51. ; Compiler compiled with #define M80, to generate short names (unique in
  52. ; 6 chars).  Set to 0 if compiler NOT compiled with M80 switch.
  53. ;
  54. M80    EQU    0
  55. ;
  56. CCDDGC:    DAD    D
  57.     JMP    CCGCHAR
  58. ;
  59. CCDSGC:    INX    H
  60.     INX    H
  61.     DAD    SP
  62. ;
  63. ; Get a single byte from the address in HL and sign extent into HL
  64. ;
  65. CCGCHAR:MOV    A,M
  66. ;
  67. ; Put the accumulator into HL and sign extend through H.
  68. ;
  69. CCARGC:
  70. CCSXT:    MOV    L,A
  71.     RLC
  72.     SBB    A
  73.     MOV    H,A
  74.     RET
  75. ;
  76. CCDDGI:    DAD    D
  77.     JMP    CCGINT
  78. ;
  79. CCDSGI:    INX    H
  80.     INX    H
  81.     DAD    SP
  82. ;
  83. ; Get a full 16-bit integer from the address in HL into HL
  84. ;
  85. CCGINT:    MOV    A,M
  86.     INX    H
  87.     MOV    H,M
  88.     MOV    L,A
  89.     RET
  90. ;
  91. CCDECC:    INX    H
  92.     INX    H
  93.     DAD    SP
  94.     MOV    D,H
  95.     MOV    E,L
  96.     CALL    CCGCHAR
  97.     DCX    H
  98.     MOV    A,L
  99.     STAX    D
  100.     RET
  101. ;
  102. CCINCC:    INX    H
  103.     INX    H
  104.     DAD    SP
  105.     MOV    D,H
  106.     MOV    E,L
  107.     CALL    CCGCHAR
  108.     INX    H
  109.     MOV    A,L
  110.     STAX    D
  111.     RET
  112. ;
  113. ;
  114. ;
  115. ; Use short symbol name
  116. ;
  117.       IF    M80
  118. CCDDPC:      ENDIF
  119. ;
  120. ; Use full length name
  121. ;
  122.       IF    NOT M80
  123. CCDDPDPC: ENDIF
  124. ;
  125.     DAD    D
  126. ;
  127. CCPDPC:    POP    B        ; Return address
  128.     POP    D
  129.     PUSH    B
  130. ;
  131. ; Store a single byte from HL at the address in DE
  132. ;
  133. CCPCHAR:
  134. PCHAR:    MOV    A,L
  135.     STAX    D
  136.     RET
  137. ;
  138. CCDECI:    INX    H
  139.     INX    H
  140.     DAD    SP
  141.     MOV    D,H
  142.     MOV    E,L
  143.     CALL    CCGINT
  144.     DCX    H
  145.     JMP    CCPINT
  146. ;
  147. CCINCI:    INX    H
  148.     INX    H
  149.     DAD    SP
  150.     MOV    D,H
  151.     MOV    E,L
  152.     CALL    CCGINT
  153.     INX    H
  154.     JMP    CCPINT
  155. ;
  156. ; Use short symbol name
  157. ;
  158.       IF    M80
  159. CCDDPI:      ENDIF
  160. ;
  161. ; Use full length name
  162. ;
  163.       IF    NOT M80
  164. CCDDPDPI: ENDIF
  165. ;
  166.     DAD    D
  167. ;
  168. CCPDPI:    POP    B        ; Return address
  169.     POP    D
  170.     PUSH    B
  171. ;
  172. ; Store a 16-bit integer in HL at the address in DE
  173. ;
  174. CCPINT:
  175. PINT:    MOV    A,L
  176.     STAX    D
  177.     INX    D
  178.     MOV    A,H
  179.     STAX    D
  180.     RET
  181. ;
  182. ; Inclusive "OR" HL and DE into HL
  183. ;
  184. CCOR:    MOV    A,L
  185.     ORA    E
  186.     MOV    L,A
  187.     MOV    A,H
  188.     ORA    D
  189.     MOV    H,A
  190.     RET
  191. ;
  192. ; Exclusive "OR" HL and DE into HL
  193. ;
  194. CCXOR:    MOV    A,L
  195.     XRA    E
  196.     MOV    L,A
  197.     MOV    A,H
  198.     XRA    D
  199.     MOV    H,A
  200.     RET
  201. ;
  202. ; "AND" HL and DE into HL
  203. ;
  204. CCAND:    MOV    A,L
  205.     ANA    E
  206.     MOV    L,A
  207.     MOV    A,H
  208.     ANA    D
  209.     MOV    H,A
  210.     RET
  211. ;
  212. ; In all the followin compare routines, HL is set to 1 if the condition
  213. ; is YES, otherwise it is set to 0 (Zero).
  214. ;
  215. ; Test if HL = DE
  216. ;
  217. CCEQ:    CALL    CCCMP
  218.     RZ
  219.     DCX    H
  220.     RET
  221. ;
  222. ; Test if DE <> HL
  223. ;
  224. CCNE:    CALL    CCCMP
  225.     RNZ
  226.     DCX    H
  227.     RET
  228. ;
  229. ; Test if DE > HL (signed)
  230. ;
  231. CCGT:    XCHG
  232.     CALL    CCCMP
  233.     RC
  234.     DCX    H
  235.     RET
  236. ;
  237. ; Test if DE <= HL (signed)
  238. ;
  239. CCLE:    CALL    CCCMP
  240.     RZ
  241.     RC
  242.     DCX    H
  243.     RET
  244. ;
  245. ; Test if DE >= HL (signed)
  246. ;
  247. CCGE:    CALL    CCCMP
  248.     RNC
  249.     DCX    H
  250.     RET
  251. ;
  252. ; Test if DE < HL (signed)
  253. ;
  254. CCLT:    CALL    CCCMP
  255.     RC
  256.     DCX    H
  257.     RET
  258. ;
  259. ; Common routine to perform a signed compare of DE and HL.  THis routine
  260. ; performs DE-HL and sets the contidions:
  261. ;
  262. ;    Carry reflects sign of difference (set means DE < HL)
  263. ;    Zero/non-Zero set according to equality.
  264. ;
  265. CCCMP:    MOV    A,H        ; Invert sign of HL
  266.     XRI    80H
  267.     MOV    H,A
  268.     MOV    A,D        ; Invert sign of DE
  269.     XRI    80H
  270.     CMP    H        ; Compare most significant bytes
  271.     JNZ    CCCMP1        ; Done if not equal
  272.     MOV    A,E        ; Compare least significant bytes
  273.     CMP    L
  274. ;
  275. CCCMP1:    LXI    H,1        ; Preset YES condition
  276.     RET
  277. ;
  278. ; Test if DE >= HL (unsigned)
  279. ;
  280. CCUGE:    CALL    CCUCMP
  281.     RNC
  282.     DCX    H
  283.     RET
  284. ;
  285. ; Test if DE < HL (unsigned)
  286. ;
  287. CCULT:    CALL    CCUCMP
  288.     RC
  289.     DCX    H
  290.     RET
  291. ;
  292. ; Test if DE > HL (unsigned)
  293. ;
  294. CCUGT:    XCHG
  295.     CALL    CCUCMP
  296.     RC
  297.     DCX    H
  298.     RET
  299. ;
  300. ; Test if DE <= HL (unsigned)
  301. ;
  302. CCULE:    CALL    CCUCMP
  303.     RZ
  304.     RC
  305.     DCX    H
  306.     RET
  307. ;
  308. ; Common routine to perform unsigned compare.  Carry set if DE < HL
  309. ; Zero/non-Zero set accordingly
  310. ;
  311. CCUCMP:    MOV    A,D
  312.     CMP    H
  313.     JNZ    CCUCP1
  314.     MOV    A,E
  315.     CMP    L
  316. ;
  317. CCUCP1:    LXI    H,1
  318.     RET
  319. ;
  320. ; Shift DE arithmetically right by HL and return in HL
  321. ;
  322. CCASR:    XCHG
  323.     DCR    E
  324.     RM
  325.     MOV    A,H
  326.     RAL
  327.     MOV    A,H
  328.     RAR
  329.     MOV    H,A
  330.     MOV    A,L
  331.     RAR
  332.     MOV    L,A
  333.     JMP    CCASR+1
  334. ;
  335. ; Shift DE arithmetically left by HL and return in HL
  336. ;
  337. CCASL:    XCHG
  338.     DCR    E
  339.     RM
  340.     DAD    H
  341.     JMP    CCASL+1
  342. ;
  343. ; Subtract HL from DE and return in HL
  344. ;
  345. CCSUB:    MOV    A,E
  346.     SUB    L
  347.     MOV    L,A
  348.     MOV    A,D
  349.     SBB    H
  350.     MOV    H,A
  351.     RET
  352. ;
  353. ; Form the two's complement of HL
  354. ;
  355. CCNEG:    CALL    CCCOM
  356.     INX    H
  357.     RET
  358. ;
  359. ; Form the one's complement of HL
  360. ;
  361. CCCOM:    MOV    A,H
  362.     CMA
  363.     MOV    H,A
  364.     MOV    A,L
  365.     CMA
  366.     MOV    L,A
  367.     RET
  368. ;
  369. ; Multiply DE by HL and return in HL.  (Signed multiply)
  370. ;
  371. CCMULT:
  372. MULT:    MOV    B,H
  373.     MOV    C,L
  374.     LXI    H,0
  375. ;
  376. CCMLT1:    MOV    A,C
  377.     RRC
  378.     JNC    CCMLT2
  379.     DAD    D
  380. ;
  381. CCMLT2:    XRA    A
  382.     MOV    A,B
  383.     RAR
  384.     MOV    B,A
  385.     MOV    A,C
  386.     RAR
  387.     MOV    C,A
  388.     ORA    B
  389.     RZ
  390.     XRA    A
  391.     MOV    A,E
  392.     RAL
  393.     MOV    E,A
  394.     MOV    A,D
  395.     RAL
  396.     MOV    D,A
  397.     ORA    E
  398.     RZ
  399.     JMP    CCMLT1
  400. ;
  401. ; Divide DE by HL and return quotient in HL, remainder in DE
  402. ; (Signed divide)
  403. ;
  404. CCDIV:
  405. DIV:    MOV    B,H
  406.     MOV    C,L
  407.     MOV    A,D
  408.     XRA    B
  409.     PUSH    PSW
  410.     MOV    A,D
  411.     ORA    A
  412.     CM    CCDENEG
  413.     MOV    A,B
  414.     ORA    A
  415.     CM    CCBCNEG
  416.     MVI    A,16
  417.     PUSH    PSW
  418.     XCHG
  419.     LXI    D,0
  420. ;
  421. CCDIV1:    DAD    H
  422.     CALL    CCRDEL
  423.     JZ    CCDIV2
  424.     CALL    CCCMPBCDE
  425.     JM    CCDIV2
  426.     MOV    A,L
  427.     ORI    1
  428.     MOV    L,A
  429.     MOV    A,E
  430.     SUB    C
  431.     MOV    E,A
  432.     MOV    A,D
  433.     SBB    B
  434.     MOV    D,A
  435. ;
  436. CCDIV2:    POP    PSW
  437.     DCR    A
  438.     JZ    CCDIV3
  439.     PUSH    PSW
  440.     JMP    CCDIV1
  441. ;
  442. CCDIV3:    POP    PSW
  443.     RP
  444.     CALL    CCDENEG
  445.     XCHG
  446.     CALL    CCDENEG
  447.     XCHG
  448.     RET
  449. ;
  450. ; Negate the integer in DE (internal routine)
  451. ;
  452. CCDENEG:MOV    A,D
  453.     CMA
  454.     MOV    D,A
  455.     MOV    A,E
  456.     CMA
  457.     MOV    E,A
  458.     INX    D
  459.     RET
  460. ;
  461. ; Negate the integer in BC (internal routine)
  462. ;
  463. CCBCNEG:MOV    A,B
  464.     CMA
  465.     MOV    B,A
  466.     MOV    A,C
  467.     CMA
  468.     MOV    C,A
  469.     INX    B
  470.     RET
  471. ;
  472. ; Rotate DE left one bit (internal routine)
  473. ;
  474. CCRDEL:    MOV    A,E
  475.     RAL
  476.     MOV    E,A
  477.     MOV    A,D
  478.     RAL
  479.     MOV    D,A
  480.     ORA    E
  481.     RET
  482. ;
  483. ; Compare BC to DE (internal routine)
  484. ;
  485. CCCMPBCDE: MOV    A,E
  486.     SUB    C
  487.     MOV    A,D
  488.     SBB    B
  489.     RET
  490. ;
  491. ; Logical negation
  492. ;
  493. CCLNEG:    MOV    A,H
  494.     ORA    L
  495.     JNZ    $+6
  496.     MVI    L,1
  497.     RET
  498.     LXI    H,0
  499.     RET
  500. ;
  501. ; Execute "switch" statement
  502. ;
  503. ; HL   =  switch value
  504. ; (SP) -> switch table
  505. ; DW ADDR1, VALUE1
  506. ; DW ADDR2, VALUE2
  507. ;
  508. ; DW 0
  509. ; [JMP default]
  510. ; Continuation
  511. ;
  512. CCSWITCH:
  513.     XCHG            ; ;DE =  switch value
  514.     POP    H        ; ;HL -> switch table
  515. ;
  516. SWLOOP:    MOV    C,M
  517.     INX    H
  518.     MOV    B,M        ; BC -> case ADDR, else 0
  519.     INX    H
  520.     MOV    A,B
  521.     ORA    C
  522.     JZ    SWEND        ; Default or continuation code
  523.     MOV    A,M
  524.     INX    H
  525.     CMP    E
  526.     MOV    A,M
  527.     INX    H
  528.     JNZ    SWLOOP
  529.     CMP    D
  530.     JNZ    SWLOOP
  531.     MOV    H,B        ; Case matched
  532.     MOV    L,C
  533. ;
  534. SWEND:    PCHL
  535. ;
  536.