home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / asmlib.lbr / MON.AZM / MON.ASM
Encoding:
Assembly Source File  |  1991-06-25  |  24.6 KB  |  1,022 lines

  1. ;****************************************************************
  2. ;*          SME Systems SBC-800 monitor programme        *
  3. ;*           Written by Steve Sparrow             *
  4. ;*    Copyright (c) 1981,2,3 SME Systems Melbourne        *
  5. ;****************************************************************
  6. ; Conversion to intel opcodes and mods to run at 100 h        *
  7. ; done by                     R.C.H. 21/5/82    *
  8. ; Jump table and substitute memory         L.I.P. 2/3/83    *
  9. ; Rationalize G command    & add P ^ and dump + ^ - variants    *
  10. ;                        R.C.H. 2/3/83    *
  11. ; Fix clock and parallel printer problems            *
  12. ; Add code for external calling and return    R.C.H. 22/3/83  *
  13. ; Add x-on/ x-off for main console        R.C.H.  7/5/83  *
  14. ; Add continuous port map command        R.C.H.  7/5/83  *
  15. ; Add enter string command            R.C.H.  7/5/83  *
  16. ; Add mods to handle blank lines better        R.C.H.  7/5/83  *
  17. ; Added NMI memory protect and halt loader    R.C.H.  7/5/83  *
  18. ; Added printer S and P messages        R.C.H.  7/5/83  *
  19. ; Added better escape handling to coe        R.C.H. 10/5/83  *
  20. ; Restored disk I/O                R.C.H. 19/7/83  *
  21. ; Modified printer dead test and nmi code       R.C.H.  3/8/83  *
  22. ; Added equate for 6 Mhz CPU operation        L.I.P.  5/8/83  *
  23. ; Added equate for VDC 8024 operation        L.I.P. 15/8/83    *
  24. ; Modified clock software            R&L    26/8/83  *
  25. ; Modified to run as stand alone monitor    R.C.H. 24/10/83 *
  26. ;****************************************************************
  27. ;
  28.     name    'mon'
  29.     public    mon
  30.     extrn    coe,cie,cst,loe,clkrd,clkwr
  31.     maclib    z80
  32. ;
  33. cr    equ    0dh
  34. lf    equ    0ah
  35. esc    equ    1bh            ; Break character
  36. ;
  37. cpos1    equ    01bh            ; Cursor positioning lead in code
  38. cpos2    equ    '='
  39. offset    equ    020h            ; Offset for vdu cursor positioioning
  40. cscrn    equ    01ah            ; Clear screen code
  41. ;
  42. ;****************************************************************
  43. ;*          start of the main program here            * 
  44. ;**************************************************************** 
  45. ;
  46. mon:
  47.     lxi    h,00
  48.     dad    sp
  49.     shld    usr$stk            ; save stack pointer
  50. ;
  51. ; Signon and start the show off
  52.     lxi    h,signon        ; Go print the message
  53.     call    ptxt
  54.     jr    warm            ; Perform a warm boot.
  55. ;
  56. signon:
  57.     db    cr,lf
  58.     db    'ASMLIB Monitor'
  59.     db    cr,lf,3
  60. signon2:
  61.     db    'M>'
  62.     db    3
  63. ;
  64. ; Warm1 is the restart address after all routines are finished.
  65. ;
  66. warm1:    
  67. warm:
  68.     lhld    usr$stk            ; set up the stack
  69.     sphl    
  70.     call    crlf            ; New line
  71.     lxi    h,signon2
  72.     call    ptxt            ; Print the M> message
  73.     call    echo            ; Get character and echo it
  74.     cpi    cr
  75.     jrz    warm1
  76.     cpi    lf
  77.     jrz    warm1
  78.     mov    c,a
  79.     push    b            ; Save character
  80.     call    prspc            ; Space across 1
  81.     call    gaddr            ; Get operands
  82.         pop    b
  83.     mov    a,c            ; Restore first command
  84.     lxi    h,warm1            ; Save address of re-entry
  85.     push    h            ; On stack
  86.     lded    opr1             ; Operand 1
  87.      lxiy    stcktop            ; Set iy to stack top
  88. ;
  89. ;****************************************************************
  90. ;*            Check key against table            *
  91. ;****************************************************************
  92. ;
  93.     sui    'A'
  94.     jrc    erdisp            ; Incorrect command
  95.     cpi    'Z'-'A'+1        ; Only A to Z allowed.
  96.     jrnc    erdisp
  97.     add    a            ; *2
  98.     push    d            ; Save it
  99.     mov    e,a
  100.     mvi    d,0            ; Index into table
  101.     lxi    h,jmptbl        ; Table of routines
  102.     dad    d            ; Point to it
  103.     mov    e,m
  104.     inx    h
  105.     mov    d,m
  106.     xchg
  107.     pop    d            ; Restore
  108.     push    h            ; Load stack with routine address
  109.     lhld    opr2
  110.     ret                ; To the routine
  111. ;
  112. ;****************************************************************
  113. ;*         Display a ? for an error prompt            *
  114. ;****************************************************************
  115. ;
  116. erdisp:
  117.     mvi    a,'?'            ; ? = illegal data
  118.     call    coe
  119.     jmp    warm1            ; Re-enter monitor
  120. ;
  121. ;****************************************************************
  122. ; Display memory as if it were a page of text. Hex data is not  *
  123. ; displayed, it is converted into a '.' to be comaptible with   *
  124. ; the dump command.                        *
  125. ;****************************************************************
  126. ;
  127. adump:
  128.     lda    opcnt
  129.     ora    a
  130.     jz    erdisp            ; No operands cause an error
  131.     cpi    1            ; 1 operand gives a screen full
  132.     jrz    scrnful
  133. ; Display from start to a finish. Start is in de, finish in hl
  134.     call    rngchk            ; Check end is after the start
  135.     lhld    opr2            ; Re-load ending address if ok.
  136. adump1:
  137.     push    h            ; Save ending address
  138.     ldax    d            ; Get the character
  139.     call    makasc            ; make it ascii into C
  140.     mov    a,c
  141.     call    coe
  142.     inx    d            ; Bump memory source address
  143.     ora    a            ; Clear carry
  144.     dsbc    d            ; Subtract current address from end 
  145.     pop    h            ; Restore the ending address
  146.     jrnz    adump1            ; When equal, next page is asked for
  147. ;
  148. ; Here we read the console for an escape or a space
  149. adwait:    ; Wait for a legitimate ascii dump command
  150.     call    cie
  151.     cpi    01bh
  152.     jz    warm1
  153.     cpi    ' '            ; next K ?
  154.     jrz    adump2
  155.     cpi    '^'            ; Previous K ?
  156.     jrz    adump3
  157.     cpi    '?'            ; Do you want to know the address ??
  158.     jrnz    adwait            ; If not this then keep on waiting
  159.     call    prhl            ; Print the current ending address
  160.     jr    adwait            ; Wait on Norelle, all things come....
  161. ;
  162. adump2:    ; Add the standard screen display amount to the end address
  163.     lxi    b,1024            ; Dsiplay the next 1k
  164.     dad    b            ; End address is now 1k on
  165.     call    crlf
  166.     jr    adump1
  167. ;
  168. adump3:    ; Display the previous k to the one on the screen
  169.     ora    a            ; Clear carry
  170.     lxi    b,2048            ; A sort of double back up is required
  171.     dsbc    b            ; HL & DE point to 2 k back
  172.     push    h
  173.     pop    d            ; Copy end into start
  174.     jr    adump2            ; Load the new end address
  175. ;
  176. ; Here the user entered only one operand so he wants a standard screenfull
  177. scrnful:
  178.     push    d
  179.     pop    h            ; Copy start address into end
  180.     jr    adump2
  181. ;
  182. ;****************************************************************
  183. ;     Execute a program at an optional address        *
  184. ;****************************************************************
  185. ;
  186. go:    lda    opcnt             ; See if operands entered
  187.     ana    a
  188.     jrz    go1            ; Use last given address
  189.     sded    temp8
  190. go1:
  191.     lhld    temp8
  192.     pchl                ; Start execution at the address
  193. ;
  194. ;****************************************************************
  195. ;*        Block move memory routine            *
  196. ;****************************************************************
  197. ;
  198. move:    call    rngchk            ; See that end > start
  199.     mov    b,h
  200.     mov    c,l            ; Bc = count of bytes
  201.     xchg        
  202.     lded    opr3            ; Get destination
  203.     ora    a
  204.     dsbc    d            ; Check no everlay
  205.     jrnc    move2            ; Skip if likely
  206.     lhld    opr3            ; Get back dest
  207.     dad    b            ; Add to byte count
  208.     dcx    h            ; Less 1
  209.     mov    d,h
  210.     mov    e,l            ; Copy to de
  211.     lhld    opr2            ; Get end
  212.     lddr                ; Fill backwards
  213.     ret
  214. ;
  215. move2:    lhld    opr1            ; Forward block move
  216.     ldir
  217. move1:    ret
  218. ;
  219. ;****************************************************************
  220. ;*        This is the hexadecimal calculator        *
  221. ;****************************************************************
  222. ;
  223. hexad:    
  224.     push    h
  225.     dad    d            ; Add opr1 and opr2
  226.     mvi    a,'+'             ; Display sum
  227.     call    coe
  228.     call    prhl            ; Display contents hl
  229.     call    prspc            ; Space
  230.     pop    h            ; Restore opr2
  231.     xchg                ; Swap opr1 and opr2
  232.     ora    a            ; Clear flags
  233.     dsbc    d            ; Subtract other way
  234.     mvi    a,'-' 
  235.     call    coe            ; Display difference
  236.     call    prhl
  237.     ret                ; Return to warm1
  238. ;
  239. ;****************************************************************
  240. ;*        Exam port contents                *
  241. ;*        cmd => i pp (x) where x means forever        *
  242. ;****************************************************************
  243. ;
  244. portin:
  245.     resy    0,12
  246.     lda    opr1            ; Get port number
  247.     mov    c,a            ; Into reg c
  248.     mvi    b,1            ; Default count
  249.     lda    opcnt            ; How many operands
  250.     cpi    2            ; 2 ?
  251.     jrc    porti1            ; Skip if less
  252.     lda    opr2            ; Get operand 2 (no.Displays)
  253.     mov    b,a            ; To reg b
  254.     ora    a            ; See if zero
  255.     jrnz    porti1            ; Skip if not
  256.     sety    0,12             ; Set flag
  257. porti1:    mov    a,c            ; Get back port no.
  258.     call    pracc            ; Display port no.+ space
  259.     inp    a
  260.     call    pracc            ; Go display value
  261.     call    chkabrt            ; See if abort pressed
  262.     push    b
  263.     call    crlf            ; New line
  264.     pop    b
  265.     bity    0,12            ; See if continuos or loop count
  266.     jrnz    porti1            ; Loop if not
  267.     djnz    porti1            ; Count - 1
  268.     ret
  269. ;
  270. ;****************************************************************
  271. ;*        Output a value to a port            *
  272. ;*        cmd => o pp (xx) (yy)                *
  273. ;*    xx= data yy = optional count, 0 = forever        *
  274. ;****************************************************************
  275. ;
  276. portout:
  277.     resy    0,12            ; Reset continous flag
  278.     lda    opr1            ; Get port no.
  279.     mov    c,a            ; To c
  280.     lda    opr2            ; Get data
  281.     mov    d,a            ; Into d
  282.     mvi    b,1            ; Default count = 1
  283.     lda    opcnt            ; See how many operands
  284.     cpi    3
  285.     jrc    pout1            ; Skip if < 3
  286.     lda    opr3            ; Get loop count
  287.     mov    b,a            ; Into reg b
  288.     ora    a            ; See if zero
  289.     jrnz    pout1            ; Skip if not
  290.     sety    0,12            ; Set continuous flag
  291. pout1:    outp    d            ; Send data
  292.     call    chkabrt            ; See if abort wanted
  293.     bity    0,12            ; Test for continuous
  294.     jrnz    pout1            ; Skip if yes
  295.     djnz    pout1            ; Counter - 1
  296.     ret
  297. ;
  298. ;****************************************************************
  299. ;*        Fill memory with data                *
  300. ;*        cmd => f ssss ffff dd                *
  301. ;****************************************************************
  302. ;
  303. fill:    lda    opr3            ; Get data to fill with
  304.     push    h            ; Save hl
  305.     call    rngchk            ; Check de < hl
  306.     pop    h
  307. fill1:    stax    d            ; Save data
  308.     push    h
  309.     ora    a            ; Clear flags leave acc.
  310.     dsbc    d            ; See if address match
  311.     pop    h            ; Restore end address
  312.     inx    d            ; Next location
  313.     jrnz    fill1            ; Skip if no match
  314.     ret
  315. ;
  316. ;****************************************************************
  317. ;*        Locate a string in memory            *
  318. ;*        cmd => l ssss ffff b1 b2 b3... B5        *
  319. ;****************************************************************
  320. ;
  321. locat:    
  322.     call    rngchk            ; Make sure end > start
  323.     lda    opcnt            ; How many operands
  324.     sui    3            ; Subtract 3
  325.     jc    erdisp            ; Error 3 minimum
  326.     mov    b,a            ; Save difference
  327.     inr    a            ; Add 1
  328.     sta    opcnt           ; Save operand count
  329.     lxi    h,opr4-1
  330.     lxi    d,opr4
  331. locat1:    ldax    d            ; Get data
  332.     mov    m,a            ; Save it
  333.     inx    h            ; Next location
  334.     inx    d
  335.     inx    d
  336.     djnz    locat1            ; Loop till all operands crushed
  337. locat2:    lda    opcnt
  338.     mov    b,a            ; Save opcount
  339.     lhld    opr1            ; Get start address
  340.     lxi    d,opr3
  341. locat3:    ldax    d            ; Get operand
  342.     cmp    m            ; Compare to memory
  343.     jrnz    locat4            ; Skip if no match
  344.     inx    h            ; Next memory location
  345.     inx    d            ; Next operand
  346.     djnz    locat3            ; Opcount - 1
  347.     lhld    opr1
  348.     call    prhl            ; Memory address
  349.     call    crlf            ; New line
  350.     call    chkabrt            ; See if abort wanted
  351. locat4:    lhld    opr2            ; Get end address
  352.     lded    opr1             ; Get start address
  353.     ora    a
  354.     dsbc    d            ; Compare them
  355.     rz                ; If same, exit
  356.     inx    d            ; Next location
  357.     sded    opr1            ; Update start address
  358.     jr    locat2            ; Loop around
  359. ;
  360. ;****************************************************************
  361. ;*        Verify 2 blocks of memory            *
  362. ;*        cmd => v ssss ffff ssss                *
  363. ;****************************************************************
  364. ;
  365. verify:    
  366.     call    rngchk            ; Check start and end address
  367.     push    h            ; Save difference
  368.     pop    b            ; Count into bc
  369.     xchg                ; Swap start and end
  370.     lded    opr3             ; Get destination block
  371. verif1:    ldax    d            ; Byte from dest
  372.     cci                ; Block compare with increment
  373.     inx    d            ; Next locat for test
  374.     jrnz    verif2            ; If no match skip
  375.     rpo                ; End of compare, exit
  376.     jr    verif1            ; Loop
  377. ;
  378. verif2:    push    psw            ; No match
  379.     push    b
  380.     push    d            ; Save all regs
  381.     dcx    h            ; Go back one location
  382.     call    prhl            ; Display pointer
  383.     mov    a,m            ; Get contents
  384.     inx    h            ; Increment pointer
  385.     call    pracc            ; Print value
  386.     pop    d
  387.     push    d
  388.     push    h
  389.     xchg                ; Get dest block
  390.     dcx    h            ; Back one
  391.     call    prhl            ; Print pointer
  392.     mov    a,m            ; Get data
  393.     call    prhex            ; Display it also
  394.     call    crlf            ; New line
  395.     pop    h
  396.     pop    d
  397.     pop    b
  398.     pop    psw            ; Restore regs
  399.     rpo
  400.     call    chkabrt            ; Test for abort key
  401.     jr    verif1            ; Then loop
  402. ;
  403. ;****************************************************************
  404. ;*        Test memory for errors                *
  405. ;*        cmd => t ssss ffff                *
  406. ;****************************************************************
  407. ;
  408. mtest:    
  409.     xchg                ; Swap start and end
  410.     inx    d            ; De = start+1
  411.     mvi    b,0            ; Count = 256
  412. mtest1:    lhld    opr1            ; Get start address
  413. mtest2:    mov    a,l
  414.     xra    h            ; Compare to h
  415.     xra    b            ; Then count
  416.     mov    m,a            ; Save in memory (auto change)
  417.     inx    h            ; Next location
  418.     push    h            ; Save pointer
  419.     ora    a            ; Clear flags
  420.     dsbc    d            ; Start - dest
  421.     pop    h            ; Restore pointer
  422.     jrnz    mtest2            ; Loop if not finished
  423.     lhld    opr1            ; Get back start address
  424. mtest3:    mov    a,l
  425.     xra    h
  426.     xra    b            ; Reconstruct data to test
  427.     cmp    m
  428.     cnz    mtest4            ; If no match, display error
  429.     inx    h            ; Next loc
  430.     push    h            ; Save it
  431.     ora    a
  432.     dsbc    d            ; See if end of test
  433.     pop    h
  434.     jrnz    mtest3            ; Skip if not
  435.     inr    b            ; Bit count done
  436.     call    chkabrt            ; See if abort wanted
  437.     mvi    a,'P'            ; Indicate 1 pass
  438.     call    coe
  439.     jr    mtest1            ; Loop to restart
  440. ;
  441. mtest4:    push    psw            ; Save test byte
  442.     call    prhl            ; Print address
  443.     pop    psw
  444.     call    pracc            ; Print test byte
  445.     mov    a,m            ; Get invalid data
  446.     call    pracc            ; Print it also
  447.     jmp    crlf            ; Display crlf, then return
  448. ;
  449. ;****************************************************************
  450. ;*        Dump memory contents                *
  451. ;*        cmd => d ssss ffff                *
  452. ;****************************************************************
  453. ;
  454. dump:    resy    0,12            ; Reset flag
  455.     xchg                ; Swap operands hl = start now
  456.     lda    opcnt            ; Get count
  457.     cpi    2            ; See if < 2
  458.     jrnc    dump2            ; Skip if so
  459. dump1:    lxi    d,255            ; Number of bytes per screen
  460.     push    h            ; Start saved
  461.     dad    d            ; Add to block
  462.     shld    opr2            ; Save as end address
  463.     pop    h            ; Restore start address
  464. dump2:    call    crlf            ; New line
  465.     push    h
  466.     pop    b            ; Get into bc
  467.     push    h
  468.     lhld    opr2            ; Hl = end address
  469.     ora    a
  470.     dsbc    b            ; Find difference
  471.     jc    erdisp            ; If range wrong, error
  472.     lxi    b,15            ; Characters per line
  473.     ora    a
  474.     dsbc    b            ; Subtract
  475.     mvi    b,16
  476.     jrz    dump3            ; End of line
  477.     jrnc    dump4
  478.     mov    a,l
  479.     add    b
  480.     mov    b,a
  481. dump3:    sety    0,12
  482. dump4:    pop    h
  483.     push    b
  484.     call    prhl2            ; Print pointer address
  485.     pop    b
  486.     call    dump6            ; Do the display
  487.     call    chkabrt            ; See if abort wanted
  488.     bity    0,12
  489.     jrz    dump2
  490. dump5:    
  491.     call    cie            ; get a character
  492.     cpi    01bh
  493.     jz    warm1
  494. ; Note that no echo done of any character entered. This is intentional
  495.     cpi    '^'            ; Display last page ?
  496.     jrz    dump7
  497.     cpi    '-'            ; Display one whole K ago ?
  498.     jrz    dump8            
  499.     cpi    '+'            ; Display next K ?
  500.     jrz    dump9            
  501.     cpi    ' '            ; Space = continue
  502.     jrnz    dump5            ; Loop till it is
  503. dump10:
  504.     resy    0,12            ; Reset screen flag
  505.     call    crlf            ; New line
  506.     jr    dump1            ; Loop round
  507. ;
  508. dump8:
  509.     ora    a            ; Clear carry
  510.     lxi    d,512+256        ; Allow to back up 1024 bytes
  511.     dsbc    d            ; by flowing into dump7
  512. ;
  513. dump7:
  514.     ora    a            ; Clear carry
  515.     lxi    d,512            ; Do a double back up
  516.     dsbc    d
  517.     jr    dump10
  518. ;
  519. dump9:
  520.     lxi    d,1024-256        ; One K from start of last display
  521.     dad    d
  522.     jr    dump10
  523. ;
  524. dump6:    push    b
  525.     push    h
  526. ;
  527. pbiny:    mov    a,m
  528.     call    pracc
  529.     call    prsep            ; Check for a separator in line middle
  530.     inx    h
  531.     djnz    pbiny            ; Print the hex values
  532.     call    prspc
  533.     call    prspc
  534.     pop    h
  535.     pop    b
  536. ;
  537. pasci:    mov    a,m            ; Print the ascii contents
  538.     inx    h            ; Bump memory pointer
  539.     call    makasc
  540.     mov    a,c
  541.     call    coe
  542.     djnz    pasci
  543.     ret
  544. ;
  545. ; Here the character in A is converted into ascii or is given a '.' if 
  546. ; hex. The result is put into c for easy access via coe.
  547. ;
  548. makasc:
  549.     ani    07fh            ; Make in the range
  550.     mov    c,a
  551.     cpi    020h            ; Lower than a space is illegal
  552.     jrc    noasc            ; Not ascii
  553.     cpi    07bh            ; Higher than upper case is illegal too
  554.     rc                ; return with ascii character in C
  555. noasc:    mvi    c,02eh            ; Replace with a '.'
  556.     ret
  557. ;
  558. ;****************************************************************
  559. ;*        Examine / alter memory locations        *
  560. ;*        cmd => e llll (xx)                *
  561. ;****************************************************************
  562. ;
  563. exmem:    
  564.     xchg                ; Hl gets start
  565. exmem1:    call    prhl            ; Display pointer
  566.     mov    a,m            ; Get byte
  567.     call    prhex            ; Print hex value
  568.     mvi    a,'-'
  569.     call    coe            ; Then marker
  570.     push    h
  571.     call    gaddr            ; Get data from user
  572.     pop    h
  573.     lda    opcnt            ; Get bytes entered
  574.     ani    3
  575.     jrz    exmem3            ; If none, skip
  576.     lda    opr1            ; Get data
  577.     mov    m,a            ; Copy to memory
  578.     inx    h            ; Next location
  579.     lda    lastchr
  580.     cpi    00dh            ; Was it a carriage ret ?
  581.     jrz    exmem1            ; Skip if so
  582. exmem2:    dcx    h            ; Restore pointer
  583.     jr    exmem1            ; Loop
  584. ;
  585. exmem3:    lda    lastchr            ; Get back last char
  586.     cpi    '^'            ; Was it an up-carrot
  587.     jrz    exmem2            ; If so, stay on this location
  588.     inx    h            ; Else next location
  589.     jr    exmem1            ; Loop around
  590. ;
  591. ;****************************************************************
  592. ;*        Port examine / modify command            *
  593. ;*        cmd => p pp                     *
  594. ;****************************************************************
  595. ;
  596. port:    ; See if display whole port space
  597.     lda    lastchr            ; Get the character
  598.     cpi    '^'            ; Carrot causes whole page
  599.     jrz    pmap
  600.     cpi    '&'
  601.     jrnz    porta
  602. ; Do a repeated port map display with cursor positioning. An escape ends it.
  603. cport:
  604.     mvi    a,cscrn            ; Erase screen code
  605.     call    coe
  606. cport1:
  607. ; DO a cursor position to line 5 column 1
  608.     mvi    a,cpos1            ; First cursor position code
  609.     call    coe
  610.     mvi    a,cpos2            ; Second cursor position code
  611.     call    coe
  612.     mvi    a,3+offset        ; Row + offset first
  613.     call    coe
  614.     mvi    a,1+offset        ; Column next
  615.     call    coe
  616.     call    pmap            ; Display the port map
  617.     jr    cport1
  618. ;
  619. pmap:
  620. ; This section causes the whole port address space to be displayed
  621.     mvi    e,16            ; Number of 16 port lines
  622.     mvi    c,00            ; Start at port 00
  623. pm1:
  624.     mvi    b,16            ; 16 ports per line displayed
  625.     mov    l,c            ; Get start port #
  626.     mvi    h,00
  627.     push    b
  628.     call    crlf            ; Space apart
  629.     call    prhl2            ; Print port #
  630.     pop    b
  631. pm2:
  632.     inp    a            ; Get the port from (c)
  633.     push    b            ; Save the counters
  634.     call    pracc            ; Print a port & a space
  635.     call    prsep            ; Check if we need a line separator
  636.     call    chkabrt            ; Detect if we need to quit-a-motto
  637.     pop    b
  638.     inr    c            ; Next port next time
  639.     djnz    pm2
  640. ; Detect if all lines have been sent to screen ( = all ports done)
  641.     dcr    e            ; Decrement line counter
  642.     mov    a,e
  643.     ora    a            ; End of the lines ?
  644.     jrnz    pm1
  645.     ret
  646. ;
  647. porta:
  648.     lda    opr1            ; Get port no
  649.     mov    c,a            ; Into c
  650. port1:    mov    a,c            ; Get back port no
  651.     call    pracc            ; Display it
  652.     inp    a            ; Get contents
  653.     call    pracc            ; Print also
  654.     push    b
  655.     call    gaddr            ; See if data to be altered
  656.     pop    b
  657.     lda    lastchr            ; Get character entered
  658.     mov    h,a
  659.     lda    opcnt            ; Get opcount
  660.     ana    a
  661.     jrz    port3            ; If none, skip
  662.     lda    opr1
  663.     outp    a            ; Send data out
  664.     mvi    a,'^'            ; Test for carrot
  665.     cmp    h
  666.     jrz    port1            ; Skip if so
  667. port2:    inr    c            ; Next port number
  668.     jr    port1            ; Loop
  669. ;
  670. port3:    mvi    a,'^'
  671.     cmp    h
  672.     jrnz    port2            ; Skip if not carrot
  673.     dcr    c            ; Port no.- 1
  674.     jr    port1
  675. ;
  676. ;****************************************************************
  677. ;         Quit the monitor                *
  678. ;****************************************************************
  679. ;
  680. quit:
  681.     lhld    usr$stk
  682.     sphl
  683.     ret
  684. ;
  685. ;****************************************************************
  686. ;      Select a memory bank using port 0ffh            *    
  687. ;****************************************************************
  688. ;
  689. bank:
  690.     lda    opcnt
  691.     cpi    1
  692.     jnz    warm1            ; Only one operand allowed
  693.     lda    opr1            ; Get port no
  694.     out    0ffh            ; set bank
  695.     jmp    warm
  696.  
  697. ;****************************************************************
  698. ;      Enter a string into memory at opr1 till an escape.       *    
  699. ;****************************************************************
  700. ;
  701. string:
  702.     lda    opcnt
  703.     cpi    1
  704.     jnz    warm1            ; Only one operand allowed
  705.     xchg                ; Put the destination address in hl
  706. ; Do a crlf then enter text till a control Z
  707.     lxi    d,00            ; Set up a character counter
  708. string1:
  709.     call    cie            ; Get a character
  710.     cpi    01ah            ; Control Z
  711.     jz    string2            ; End of the command.
  712.     mov    m,a            ; Put into memory
  713.     call    coe            ; Echo to screen
  714.     inx    h
  715.     inx    d            ; Bump pointers
  716.     jr    string1
  717. string2:    ; Here when the user has had enough and entered a control Z
  718.     call    crlf
  719.     xchg                ; Put character counter into hl
  720.     mvi    a,'>'
  721.     call    coe
  722.     call    prhl            ; Print the number of characters
  723.     jmp    warm            ; Process next command
  724. ;
  725. ;****************************************************************
  726. ;*    Clock routines to set and clear the clock registers    *
  727. ;****************************************************************
  728. ;
  729. clock:    lxi    h,clkstrg        ; Clock string
  730.     lda    opcnt
  731.     ora    a            ; See if set/display
  732.     jrz    readit
  733. ;
  734. writit:    cpi    7            ; Should be 7 operands (0-6)
  735.     jc    erdisp            ; Error not enough
  736.     lxi    d,opr1
  737.     mvi    b,7
  738. writ0:    ldax    d
  739.     mov    m,a
  740.     inx    d
  741.     inx    d
  742.     inx    h
  743.     djnz    writ0
  744.     lxi    d,clkstrg
  745.     call    clkwr            ; Go write clock
  746.     ret
  747. ;
  748. readit:
  749.     lxi    d,clkstrg
  750.     call    clkrd            ; Go read clock string
  751.     lxix    clkstrg            ; Point to it
  752.     ldx    a,2
  753.     call    prhex            ; Print date
  754.     mvi    a,'-'
  755.     call    coe
  756.     ldx    a,1
  757.     call    prhex
  758.     mvi    a,'-'
  759.     call    coe
  760.     ldx    a,0
  761.     call    pracc            ; Print year
  762.     call    prspc            ; And extra space
  763.     ldx    a,4            ; Skip to hours
  764.     call    prhex
  765.     mvi    a,':'
  766.     call    coe
  767.     ldx    a,5
  768.     call    prhex
  769.     mvi    a,':'
  770.     call    coe
  771.     ldx    a,6
  772.     call    prhex
  773.     call    crlf
  774.     ret
  775. ;
  776. chkabrt:    ; Detect if the user wanted to quit or not
  777.     call    cst            ; See if abort pressed
  778.     rz                ; Return if no character pending
  779.     call    cie            ; Get the character, conin handles esc
  780.     cpi    01bh
  781.     jz    warm1
  782.     cpi    '.'
  783.     jz    warm1
  784.     ret
  785. ;
  786. ;****************************************************************
  787. ;*        See if de less than hl                *
  788. ;****************************************************************
  789. ;
  790. rngchk:    ora    a            ; Clear flags
  791.     dsbc    d
  792.     jc    erdisp
  793.     inx    h
  794.     ret
  795. ;
  796. pracc:    push    b
  797.     call    prhex
  798.     call    prspc
  799.     pop    b
  800.     ret
  801. ;
  802. crlf:    mvi    a,00dh
  803.     call    coe
  804.     mvi    a,10
  805.     jmp    coe
  806. ;
  807. prspc:    mvi    a,' '
  808.     jmp    coe
  809. ;
  810. ptxt:    mov    a,m
  811.     cpi    003h
  812.     rz    
  813.     call    coe
  814.     inx    h
  815.     jr    ptxt
  816. ;
  817. prhex:    push    psw
  818.     rrc
  819.     rrc
  820.     rrc
  821.     rrc
  822.     call    phex1
  823.     pop    psw
  824. phex1:    ani    00fh
  825.     adi    090h
  826.     daa
  827.     aci    040h
  828.     daa
  829.     jmp    coe
  830. ;
  831. makhex:    sui    '0'            ; Remove ascii bias
  832.     cpi    10            ; If 0 - 9, return
  833.     rm
  834.     sui    7            ; Else make a - f = 10 - 15
  835.     ret
  836. ;
  837. valnum:    cpi    '0'
  838.     jrc    valbad            ; Check = '0' - '9'
  839.     cpi    '9'+1
  840.     jrc    valnok
  841.     cpi    'A'-1            ; Check = 'A' - 'F'
  842.     jrc    valbad
  843.     cpi    'G'
  844.     jrnc    valbad
  845. valnok:    xra    a            ; Set zero flag for good exit
  846.     ret
  847. ;
  848. valbad:    xra    a            ; Set acc = 1
  849.     inr    a
  850.     ret
  851. ;
  852. ;****************************************************************
  853. ;*        Checks for end of numeric entry            *
  854. ;****************************************************************
  855. ;
  856. valdm:    cpi    ' '            ; valid delim
  857.     rz    
  858.     cpi    '^'            ; Alternate code for cr (*)
  859.     jrz    valdm1
  860.     cpi    '&'            ; This is allowed for cont' commands
  861.     jrz    valdm1
  862.     cpi    cr            ; End of command
  863.     rnz                ; Exit if not a one of these
  864. ;
  865. valdm1:    push    b            ; Save counters etc
  866.     call    crlf            ; Issue a carriage return
  867.     pop    b
  868.     xra    a            ; Set zero flag = valid delim
  869.     ret
  870. ;
  871. ghex:
  872.     lxi    h,00
  873.     mov    b,l
  874. ghex1:
  875.     call    echo
  876.     inr    b
  877.     call    valdm
  878.     rz
  879.     call    valnum
  880.     rnz
  881.     mov    a,c
  882.     call    makhex
  883.     dad    h
  884.     dad    h
  885.     dad    h
  886.     dad    h
  887.     add    l            ; add in lower digit
  888.     mov    l,a            ; put back in
  889.     jr    ghex1
  890. ;
  891. echo:    call    cie
  892.     ani    07fh
  893.     cpi    'a'            ; Ensure in upper case
  894.     jrc    noconv
  895.     cpi    'z'+1
  896.     jrnc    noconv
  897.     ani    05fh
  898. noconv:
  899.     mov    c,a            ; save
  900.     call    coe            ; echo to console converted
  901.     ret
  902. ;
  903. ;****************************************************************
  904. ;*    Collect up to 9 bytes of numeric data            *
  905. ;*    separated by spaces if entered                *
  906. ;****************************************************************
  907. ;
  908. gaddr:
  909.     xra    a
  910.     lxi    h,opr1
  911.     push    h
  912.     popix
  913.     mov    m,a
  914.     lxi    b,13
  915.     lxi    d,opr1+1
  916.     ldir                ; Clear 13 bytes of ram
  917.     sta    opcnt
  918. ;
  919. gaddr1:
  920.     call    ghex
  921.     jnz    erdisp
  922.     mov    a,c
  923.     sta    lastchr
  924.     cpi    ' '
  925.     jrz    gaddr2
  926.     dcr    b
  927.     rz
  928. gaddr2:
  929.     stx    l,000h
  930.     stx    h,001h
  931.     lda    opcnt
  932.     inr    a
  933.     sta    opcnt
  934.     inxix
  935.     inxix
  936.     mov    a,c
  937.     cpi    ' '
  938.     jrz    gaddr1
  939.     ret
  940. ;
  941. prhl:    mov    a,h
  942.     call    prhex
  943.     mov    a,l
  944.     jmp    pracc
  945. ;
  946. prhl2:    ; Print contents of hl and also extra spaces 
  947.     call    prhl    
  948.     jr    prsep2            ; Send an additional space
  949. ;
  950. prsep:    ; If b = 8 then print a '- ' else return
  951.     mov    a,b
  952.     cpi    9            ; Already done 8 characters ??
  953.     rnz                ; Return if not at exact match
  954.     mvi    a,'-'
  955.     call    coe
  956. prsep2:
  957.     jmp    prspc            ; Print a space
  958. ;
  959. ;****************************************************************
  960. ;*        Printer output routine                *
  961. ;****************************************************************
  962. ;
  963. poe:    
  964.     mov    a,c
  965.     jmp    loe
  966. ;
  967. ;************************************************
  968. ;*    Table of routines for indirect jump    *
  969. ;************************************************
  970. ;
  971. jmptbl:
  972.     dw    adump            ; A Ascii display of memory
  973.     dw    bank            ; B Set memory bank using port 0FFh
  974.     dw    erdisp            ; error
  975.     dw    dump            ; D display memory
  976.     dw    exmem            ; E examine memory
  977.     dw    fill            ; F fill memory
  978.     dw    go            ; G go to program
  979.     dw    hexad            ; H hex sum and difference
  980.     dw    portin            ; I input from port
  981.     dw    erdisp            ; J
  982.     dw    clock            ; K read/write clock
  983.     dw    locat            ; L locate string
  984.     dw    move            ; M move memory
  985.     dw    erdisp            ; N
  986.     dw    portout            ; O output to a port
  987.     dw    port            ; P examine port
  988.     dw    quit              ; quit this monitor
  989.     dw    erdisp            ; error
  990.     dw    exmem            ; S Substitute memory duplicate
  991.     dw    mtest            ; T test ram
  992.     dw    string            ; U User the console for writing to ram
  993.     dw    verify            ; V verify ram
  994.     dw    erdisp            ; error
  995.     dw    erdisp            ; X
  996.     dw    erdisp            ; error
  997.     dw    erdisp            ; error
  998. ;
  999.     dseg
  1000. ;
  1001.     ds    10
  1002. stcktop
  1003.     ds    10
  1004. opcnt    db    00
  1005. lastchr    db    00
  1006. opr1    db    00,00
  1007. opr2    db    00,00
  1008. opr3    db    00,00
  1009. opr4    db    00,00
  1010. opr5    db    00,00
  1011. opr6    db    00,00
  1012. opr7    db    00,00
  1013. temp2    db    00,00
  1014. temp6    db    00,00
  1015. temp8    db    00,00
  1016. clkstrg    db    0,0,0,0,0,0,0
  1017. usr$stk    db    00,00
  1018. ;
  1019.     end
  1020.  
  1021.  
  1022.