Advertisement
Guest User

zOS.asm

a guest
May 11th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define mem $7c
  2. #define key_buff $a000
  3. .org $0000
  4. kernel:
  5.     JP kmain
  6.     .db 0,0,0,0,0
  7.  
  8. ; TX:
  9. .org $0008
  10. printR:
  11.     JP printc
  12.     .db 0,0,0,0,0
  13.  
  14. ;RX
  15. .org $0010
  16. getR:
  17.     JP getc
  18.     .db 0,0,0,0,0
  19.  
  20. ; check character
  21. .org $0018
  22. chkC:
  23.     JP rx_ready
  24.     .db 0,0,0,0,0
  25.    
  26. ; print nibble
  27. .org $0020
  28. printn:
  29.     JP print_nibble
  30.  
  31.  
  32. kmain:
  33.     ld sp, $ff00
  34.     ld a,$00
  35.     ld (key_buff),a
  36.     ld hl, message
  37.     call prints
  38.     jp prompt
  39.    
  40. prompt:
  41.     ld hl, sym
  42.     call prints
  43.     call gets
  44. testChar:
  45.     ld a,(key_buff)
  46.     cp 'w'
  47.     jp z,write
  48.     cp 'r'
  49.     jp z,read
  50.     cp 'j'
  51.     jp z,jump
  52.     cp 'd'
  53.     jp z,dump
  54.     ld hl,errMsg
  55.     call prints
  56.     jp prompt
  57.    
  58. write:
  59.     ld a,'$'
  60.     call printc
  61.     call get_word
  62.     call new_line
  63.     ld a,'#'
  64.     call printc
  65.     call get_byte
  66.     call new_line
  67.     ld (hl),a
  68.     jp prompt
  69.    
  70. read:
  71.     ld a,'%'
  72.     call printc
  73.     call get_word
  74.     call new_line
  75.     ld a,(hl)
  76.     call print_byte
  77.     jp prompt
  78.    
  79. jump:
  80.     ld a,'?'
  81.     call printc
  82.     call get_word
  83.     call new_line
  84.     ld bc, prompt
  85.     push bc
  86.     jp (hl)
  87.     jp prompt
  88.    
  89. ;Dump routines from vaxman.de
  90.    
  91. dump:            
  92.     push    af
  93.                 push    bc
  94.                 push    de
  95.                 push    hl
  96.                 ld      hl, dump_msg_1
  97.                 call    prints            ; Print prompt
  98.                 call    get_word        ; Read start address
  99.                 push    hl              ; Save start address
  100.                 ld      hl, dump_msg_2  ; Prompt for end address
  101.                 call    prints
  102.                 call    get_word        ; Get end address
  103.                 call    new_line
  104.                 inc     hl              ; Increment stop address for comparison
  105.                 push hl
  106.                 pop de
  107.                 pop     hl              ; HL is the start address again
  108.                 ; This loop will dump 16 memory locations at once - even
  109.                 ; if this turns out to be more than requested.
  110. dump_line:      
  111.     ld      b, $10          ; This loop will process 16 bytes
  112.                 push    hl              ; Save HL again
  113.                 call    print_word      ; Print address
  114.                 ld      hl, dump_msg_3  ; and a colon
  115.                 call    prints
  116.                 pop hl                  ; Restore address
  117.                 push    hl              ; We will need HL for the ASCII dump
  118. dump_loop:      
  119.     ld      a, (hl)         ; Get the memory content
  120.                 call    print_byte      ; and print it
  121.                 ld      a, ' '          ; Print a space
  122.                 call    printc
  123.                 inc     hl              ; Increment address counter
  124.                 djnz    dump_loop       ; Continue with this line
  125.                 ; This loop will dump the very same 16 memory locations - but
  126.                 ; this time printable ASCII characters will be written.
  127.                 ld      b, $10          ; 16 characters at a time
  128.                 ld      a, ' '          ; We need some spaces
  129.                 call    printc            ; to print
  130.                 call    printc
  131.                 pop     hl              ; Restore the start address
  132. dump_ascii_loop:
  133.     ld      a, (hl)         ; Get byte
  134.                 call    is_print        ; Is it printable?
  135.                 jr      c, dump_al_1    ; Yes
  136.                 ld      a, '.'          ; No - print a dot
  137. dump_al_1:      
  138.     call    printc            ; Print the character
  139.                 inc     hl              ; Increment address to read from
  140.                 djnz    dump_ascii_loop
  141.                 ; Now we are finished with printing one line of dump output.
  142.                 call    new_line            ; CR/LF for next line on terminal
  143.                 push    hl              ; Save the current address for later
  144.                 and     a               ; Clear carry
  145.                 sbc     hl, de          ; Have we reached the last address?
  146.                 pop     hl              ; restore the address
  147.                 jr      c, dump_line    ; Dump next line of 16 bytes
  148.                 pop     hl
  149.                 pop     de
  150.                 pop     bc
  151.                 pop     af
  152.                 ret
  153. dump_msg_1:      
  154.     .db    "DUMP: START=", 0
  155. dump_msg_2:      
  156.     .db    " END=", 0
  157. dump_msg_3:      
  158.     .db    ": ", 0
  159.    
  160.    
  161. message:
  162.     .db "Z80 Monitor 0.0.2",0
  163.    
  164. sym:
  165.     .db ">",0
  166. errMsg:
  167.     .db "Not a command",0
  168.    
  169.  
  170. ;Subroutines
  171.    
  172. prints:
  173.     ld a, (hl)
  174.     call printc
  175.     inc hl
  176.     cp 0
  177.     jp nz, prints
  178.     ret z
  179.    
  180. printc:
  181.     call tx_ready
  182.     out (mem),a
  183.     ret
  184.    
  185. gets:
  186.     push af
  187.     push hl
  188.     push bc
  189.     ld hl,key_buff
  190. loop1:
  191.     call getc
  192.     cp $0D
  193.     jp z,return1
  194.     call printc
  195.     ld (hl),a
  196.     inc hl
  197.     jp loop1
  198. return1:
  199.     call printc
  200.     pop af
  201.     pop hl
  202.     pop bc
  203.     ret
  204.    
  205. getc:
  206.     call rx_ready
  207.     in a,(mem)
  208.     ret
  209.    
  210. get_byte:        
  211.     push    bc              ; Save contents of B (and C)
  212.     call    get_nibble      ; Get upper nibble
  213.     rlc     a
  214.     rlc     a
  215.     rlc     a
  216.     rlc     a
  217.     ld      b, a            ; Save upper four bits
  218.     call    get_nibble      ; Get lower nibble
  219.     or      b               ; Combine both nibbles
  220.     pop     bc              ; Restore B (and C)
  221.     ret
  222. ;
  223. ; Get a hexadecimal digit from the serial line. This routine blocks until
  224. ; a valid character (0-9a-f) has been entered. A valid digit will be echoed
  225. ; to the serial line interface. The lower 4 bits of A contain the value of
  226. ; that particular digit.
  227. ;
  228. get_nibble:
  229.     call    getc            ; Read a character
  230.     call    is_hex          ; Was it a hex digit?
  231.     jr      nc, get_nibble  ; No, get another character
  232.     call    nibble2val      ; Convert nibble to value
  233.     call    print_nibble
  234.     ret
  235. ;
  236. ; Get a word (16 bit) in hexadecimal notation. The result is returned in HL.
  237. ; Since the routines get_byte and therefore get_nibble are called, only valid
  238. ; characters (0-9a-f) are accepted.
  239. ;
  240. get_word:
  241.     push    af
  242.     call    get_byte        ; Get the upper byte
  243.     ld      h, a
  244.     call    get_byte        ; Get the lower byte
  245.     ld      l, a
  246.     pop     af
  247.     ret
  248.    
  249. ;
  250. ; print_byte prints a single byte in hexadecimal notation to the serial line.
  251. ; The byte to be printed is expected to be in A.
  252. ;
  253. print_byte:    
  254.     push    af              ; Save the contents of the registers
  255.     push    bc
  256.     ld      b, a
  257.     rrca
  258.     rrca
  259.     rrca
  260.     rrca
  261.     call    print_nibble    ; Print high nibble
  262.     ld      a, b
  263.     call    print_nibble    ; Print low nibble
  264.     pop     bc              ; Restore original register contents
  265.     pop     af
  266.     ret
  267. ;
  268. ; print_nibble prints a single hex nibble which is contained in the lower
  269. ; four bits of A:
  270. ;
  271. print_nibble:
  272.     push    af              ; We won't destroy the contents of A
  273.     and     $f              ; Just in case...
  274.     add     a,'0'             ; If we have a digit we are done here.
  275.     cp      '9' + 1         ; Is the result > 9?
  276.     jr      c, print_nibble_1
  277.     add     a,'a' - '0' - $a  ; Take care of A-F
  278. print_nibble_1:
  279.     call    printc            ; Print the nibble and
  280.     pop     af              ; restore the original value of A
  281.     ret
  282.    
  283.  
  284. print_word:      
  285.     push    hl
  286.     push    af
  287.     ld      a, h
  288.     call    print_byte
  289.     ld      a, l
  290.     call    print_byte
  291.     pop     af
  292.     pop     hl
  293.     ret  
  294. ;
  295. ; is_hex checks a character stored in A for being a valid hexadecimal digit.
  296. ; A valid hexadecimal digit is denoted by a set C flag.
  297. ;
  298. is_hex:
  299.     cp      'f' + 1         ; Greater than 'f'?
  300.     ret     nc              ; Yes
  301.     cp      '0'             ; Less than '0'?
  302.     jr      nc, is_hex_1    ; No, continue
  303.     ccf                     ; Complement carry (i.e. clear it)
  304.     ret
  305. is_hex_1:  
  306.     cp      '9' + 1         ; Less or equal '9*?
  307.     ret     c               ; Yes
  308.     cp      'a'             ; Less than 'a'?
  309.     jr      nc, is_hex_2    ; No, continue
  310.     ccf                     ; Yes - clear carry and return
  311.     ret
  312. is_hex_2:  
  313.     scf                     ; Set carry
  314.     ret
  315.    
  316. is_print:    
  317.     cp      $20
  318.                 jr      nc, is_print_1
  319.                 ccf
  320.                 ret
  321. is_print_1:
  322.     cp      $7f
  323.                 ret
  324.  
  325. ;
  326. ; nibble2val expects a hexadecimal digit (upper case!) in A and returns the
  327. ; corresponding value in A.
  328. ;
  329. nibble2val:  
  330.     cp      '9' + 1         ; Is it a digit (less or equal '9')?
  331.     jr      c, nibble2val_1 ; Yes
  332.     sub     7               ; Adjust for A-F
  333. nibble2val_1:  
  334.     sub     '0'             ; Fold back to 0..15
  335.     and     $f              ; Only return lower 4 bits
  336.     ret
  337.  
  338.    
  339. ;
  340. ; Wait for an incoming character on the serial line:
  341. ;
  342. rx_ready:        
  343.     push    af
  344. rx_ready_loop:  
  345.     in      a, ($7d)
  346.     bit     0, a
  347.     jr      z, rx_ready_loop
  348.     pop     af
  349.     ret
  350. ;
  351. ; Wait for UART to become ready to transmit a byte:
  352. ;
  353. tx_ready:
  354.     push    af
  355. tx_ready_loop:
  356.     in      a, ($7d)
  357.     bit     1, a
  358.     jr      z, tx_ready_loop
  359.     pop af
  360.     ret
  361.  
  362. new_line:
  363.     push af
  364.     ld a,$0D
  365.     call printc
  366.     pop af
  367.     ret
  368.    
  369. tab:
  370.     push af
  371.     ld a,$09
  372.     call printc
  373.     pop af
  374.     ret
  375.    
  376.  
  377. ;21 00 20 7E CF FE 00 CA 0E 10 23 C3 03 10 C7 59 4F 00
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement