Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define mem $7c
- #define key_buff $a000
- .org $0000
- kernel:
- JP kmain
- .db 0,0,0,0,0
- ; TX:
- .org $0008
- printR:
- JP printc
- .db 0,0,0,0,0
- ;RX
- .org $0010
- getR:
- JP getc
- .db 0,0,0,0,0
- ; check character
- .org $0018
- chkC:
- JP rx_ready
- .db 0,0,0,0,0
- ; print nibble
- .org $0020
- printn:
- JP print_nibble
- kmain:
- ld sp, $ff00
- ld a,$00
- ld (key_buff),a
- ld hl, message
- call prints
- jp prompt
- prompt:
- ld hl, sym
- call prints
- call gets
- testChar:
- ld a,(key_buff)
- cp 'w'
- jp z,write
- cp 'r'
- jp z,read
- cp 'j'
- jp z,jump
- cp 'd'
- jp z,dump
- ld hl,errMsg
- call prints
- jp prompt
- write:
- ld a,'$'
- call printc
- call get_word
- call new_line
- ld a,'#'
- call printc
- call get_byte
- call new_line
- ld (hl),a
- jp prompt
- read:
- ld a,'%'
- call printc
- call get_word
- call new_line
- ld a,(hl)
- call print_byte
- jp prompt
- jump:
- ld a,'?'
- call printc
- call get_word
- call new_line
- ld bc, prompt
- push bc
- jp (hl)
- jp prompt
- ;Dump routines from vaxman.de
- dump:
- push af
- push bc
- push de
- push hl
- ld hl, dump_msg_1
- call prints ; Print prompt
- call get_word ; Read start address
- push hl ; Save start address
- ld hl, dump_msg_2 ; Prompt for end address
- call prints
- call get_word ; Get end address
- call new_line
- inc hl ; Increment stop address for comparison
- push hl
- pop de
- pop hl ; HL is the start address again
- ; This loop will dump 16 memory locations at once - even
- ; if this turns out to be more than requested.
- dump_line:
- ld b, $10 ; This loop will process 16 bytes
- push hl ; Save HL again
- call print_word ; Print address
- ld hl, dump_msg_3 ; and a colon
- call prints
- pop hl ; Restore address
- push hl ; We will need HL for the ASCII dump
- dump_loop:
- ld a, (hl) ; Get the memory content
- call print_byte ; and print it
- ld a, ' ' ; Print a space
- call printc
- inc hl ; Increment address counter
- djnz dump_loop ; Continue with this line
- ; This loop will dump the very same 16 memory locations - but
- ; this time printable ASCII characters will be written.
- ld b, $10 ; 16 characters at a time
- ld a, ' ' ; We need some spaces
- call printc ; to print
- call printc
- pop hl ; Restore the start address
- dump_ascii_loop:
- ld a, (hl) ; Get byte
- call is_print ; Is it printable?
- jr c, dump_al_1 ; Yes
- ld a, '.' ; No - print a dot
- dump_al_1:
- call printc ; Print the character
- inc hl ; Increment address to read from
- djnz dump_ascii_loop
- ; Now we are finished with printing one line of dump output.
- call new_line ; CR/LF for next line on terminal
- push hl ; Save the current address for later
- and a ; Clear carry
- sbc hl, de ; Have we reached the last address?
- pop hl ; restore the address
- jr c, dump_line ; Dump next line of 16 bytes
- pop hl
- pop de
- pop bc
- pop af
- ret
- dump_msg_1:
- .db "DUMP: START=", 0
- dump_msg_2:
- .db " END=", 0
- dump_msg_3:
- .db ": ", 0
- message:
- .db "Z80 Monitor 0.0.2",0
- sym:
- .db ">",0
- errMsg:
- .db "Not a command",0
- ;Subroutines
- prints:
- ld a, (hl)
- call printc
- inc hl
- cp 0
- jp nz, prints
- ret z
- printc:
- call tx_ready
- out (mem),a
- ret
- gets:
- push af
- push hl
- push bc
- ld hl,key_buff
- loop1:
- call getc
- cp $0D
- jp z,return1
- call printc
- ld (hl),a
- inc hl
- jp loop1
- return1:
- call printc
- pop af
- pop hl
- pop bc
- ret
- getc:
- call rx_ready
- in a,(mem)
- ret
- get_byte:
- push bc ; Save contents of B (and C)
- call get_nibble ; Get upper nibble
- rlc a
- rlc a
- rlc a
- rlc a
- ld b, a ; Save upper four bits
- call get_nibble ; Get lower nibble
- or b ; Combine both nibbles
- pop bc ; Restore B (and C)
- ret
- ;
- ; Get a hexadecimal digit from the serial line. This routine blocks until
- ; a valid character (0-9a-f) has been entered. A valid digit will be echoed
- ; to the serial line interface. The lower 4 bits of A contain the value of
- ; that particular digit.
- ;
- get_nibble:
- call getc ; Read a character
- call is_hex ; Was it a hex digit?
- jr nc, get_nibble ; No, get another character
- call nibble2val ; Convert nibble to value
- call print_nibble
- ret
- ;
- ; Get a word (16 bit) in hexadecimal notation. The result is returned in HL.
- ; Since the routines get_byte and therefore get_nibble are called, only valid
- ; characters (0-9a-f) are accepted.
- ;
- get_word:
- push af
- call get_byte ; Get the upper byte
- ld h, a
- call get_byte ; Get the lower byte
- ld l, a
- pop af
- ret
- ;
- ; print_byte prints a single byte in hexadecimal notation to the serial line.
- ; The byte to be printed is expected to be in A.
- ;
- print_byte:
- push af ; Save the contents of the registers
- push bc
- ld b, a
- rrca
- rrca
- rrca
- rrca
- call print_nibble ; Print high nibble
- ld a, b
- call print_nibble ; Print low nibble
- pop bc ; Restore original register contents
- pop af
- ret
- ;
- ; print_nibble prints a single hex nibble which is contained in the lower
- ; four bits of A:
- ;
- print_nibble:
- push af ; We won't destroy the contents of A
- and $f ; Just in case...
- add a,'0' ; If we have a digit we are done here.
- cp '9' + 1 ; Is the result > 9?
- jr c, print_nibble_1
- add a,'a' - '0' - $a ; Take care of A-F
- print_nibble_1:
- call printc ; Print the nibble and
- pop af ; restore the original value of A
- ret
- print_word:
- push hl
- push af
- ld a, h
- call print_byte
- ld a, l
- call print_byte
- pop af
- pop hl
- ret
- ;
- ; is_hex checks a character stored in A for being a valid hexadecimal digit.
- ; A valid hexadecimal digit is denoted by a set C flag.
- ;
- is_hex:
- cp 'f' + 1 ; Greater than 'f'?
- ret nc ; Yes
- cp '0' ; Less than '0'?
- jr nc, is_hex_1 ; No, continue
- ccf ; Complement carry (i.e. clear it)
- ret
- is_hex_1:
- cp '9' + 1 ; Less or equal '9*?
- ret c ; Yes
- cp 'a' ; Less than 'a'?
- jr nc, is_hex_2 ; No, continue
- ccf ; Yes - clear carry and return
- ret
- is_hex_2:
- scf ; Set carry
- ret
- is_print:
- cp $20
- jr nc, is_print_1
- ccf
- ret
- is_print_1:
- cp $7f
- ret
- ;
- ; nibble2val expects a hexadecimal digit (upper case!) in A and returns the
- ; corresponding value in A.
- ;
- nibble2val:
- cp '9' + 1 ; Is it a digit (less or equal '9')?
- jr c, nibble2val_1 ; Yes
- sub 7 ; Adjust for A-F
- nibble2val_1:
- sub '0' ; Fold back to 0..15
- and $f ; Only return lower 4 bits
- ret
- ;
- ; Wait for an incoming character on the serial line:
- ;
- rx_ready:
- push af
- rx_ready_loop:
- in a, ($7d)
- bit 0, a
- jr z, rx_ready_loop
- pop af
- ret
- ;
- ; Wait for UART to become ready to transmit a byte:
- ;
- tx_ready:
- push af
- tx_ready_loop:
- in a, ($7d)
- bit 1, a
- jr z, tx_ready_loop
- pop af
- ret
- new_line:
- push af
- ld a,$0D
- call printc
- pop af
- ret
- tab:
- push af
- ld a,$09
- call printc
- pop af
- ret
- ;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