Updated
This commit is contained in:
51
OperatingSystem/monitor_v2/include/addresses.s
Normal file
51
OperatingSystem/monitor_v2/include/addresses.s
Normal file
@@ -0,0 +1,51 @@
|
||||
CS_BANK equ 0000000b
|
||||
CS_DIP equ 0000001b
|
||||
CS_CTC_0 equ 0000100b
|
||||
CS_CTC_1 equ 0000101b
|
||||
CS_CTC_2 equ 0000110b
|
||||
CS_CTC_3 equ 0000111b
|
||||
CS_SIO_A_D equ 0001000b
|
||||
CS_SIO_A_C equ 0001001b
|
||||
CS_SIO_B_D equ 0001010b
|
||||
CS_SIO_B_C equ 0001011b
|
||||
|
||||
IO_RTC_SEC0 equ 00100000b
|
||||
IO_RTC_SEC1 equ 00100001b
|
||||
IO_RTC_MIN0 equ 00100010b
|
||||
IO_RTC_MIN1 equ 00100011b
|
||||
IO_RTC_HOUR equ 00100100b
|
||||
IO_RTC_AMPM equ 00100101b
|
||||
IO_RTC_DAY0 equ 00100110b
|
||||
IO_RTC_DAY1 equ 00100111b
|
||||
IO_RTC_MON0 equ 00101000b
|
||||
IO_RTC_MON1 equ 00101001b
|
||||
IO_RTC_YERR0 equ 00101010b
|
||||
IO_RTC_YEAR1 equ 00101011b
|
||||
IO_RTC_WEEK equ 00101100b
|
||||
IO_RTC_CTR_D equ 00101101b
|
||||
IO_RTC_CTR_E equ 00101110b
|
||||
IO_RTC_CTR_F equ 00101111b
|
||||
|
||||
IO_AY0_ADDR equ 01000000b ;64
|
||||
IO_AY0_DATA equ 01000001b ;65
|
||||
IO_AY1_ADDR equ 01000010b ;66
|
||||
IO_AY1_DATA equ 01000011b ;67
|
||||
|
||||
START_ROM equ 0x0000
|
||||
IO_REG0 equ 0x20
|
||||
|
||||
VDP_REG equ 0x81
|
||||
VDP_MEM equ 0x80
|
||||
|
||||
PROG_ROM_START equ 0x0100
|
||||
PROG_MEM_START equ 04000h
|
||||
|
||||
IO_PIO_0_A_D equ 0x60
|
||||
IO_PIO_0_A_C equ 0x61
|
||||
IO_PIO_0_B_D equ 0x62
|
||||
IO_PIO_0_B_C equ 0x63
|
||||
|
||||
IO_PIO_1_A_D equ 0x64 ;PS2
|
||||
IO_PIO_1_A_C equ 0x65
|
||||
IO_PIO_1_B_D equ 0x66
|
||||
IO_PIO_1_B_C equ 0x67
|
||||
4564
OperatingSystem/monitor_v2/include/basic.s
Normal file
4564
OperatingSystem/monitor_v2/include/basic.s
Normal file
File diff suppressed because it is too large
Load Diff
115
OperatingSystem/monitor_v2/include/bootldr.s
Normal file
115
OperatingSystem/monitor_v2/include/bootldr.s
Normal file
@@ -0,0 +1,115 @@
|
||||
; Z8C Bootloader
|
||||
; 2022 by Dennis Gunia
|
||||
|
||||
BTLDR_ENTRY:
|
||||
;ld SP, 0ffffh ; set stack pointer
|
||||
|
||||
;Setup Serial Interface
|
||||
LD A,01001111b ; External Trigger, Time Constant Follows
|
||||
OUT (CS_CTC_0),A
|
||||
IN A,(CS_DIP) ; Read BAUD from DIP-Switches
|
||||
OUT (CS_CTC_0),A
|
||||
LD A,00110000b ;write into WR0: error reset, select WR0
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,018h ;write into WR0: channel reset
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,004h ;write into WR0: select WR4
|
||||
OUT (CS_SIO_A_C),A
|
||||
;LD a,04h ;write into WR4: clkx1,1 stop bit, no parity
|
||||
LD a,01000100b ;write into WR4: clkx16,1 stop bit, no parity
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,005h ;write into WR0: select WR5
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,11101000b ;DTR inactive, TX 8bit, BREAK off, TX on, RTS inactive
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,01h ;write into WR0: select WR1
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,00000100b ;no interrupt in CH B, special RX condition affects vect
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,02h ;write into WR0: select WR2
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,0h ;write into WR2: cmd line int vect (see int vec table)
|
||||
;bits D3,D2,D1 are changed according to RX condition
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,003h ;write into WR0: select WR3
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,0C1h ;RX 8bit, auto enable off, RX on
|
||||
OUT (CS_SIO_A_C),A
|
||||
|
||||
BTLDR_STARTUP_MSG:
|
||||
LD HL,[S_BTLDR_STARTUP_MSG]
|
||||
BTLDR_STARTUP_MSG_LOOP:
|
||||
LD A,(HL)
|
||||
OR A
|
||||
JR Z, BTLDR_INPUT
|
||||
CALL BTLDR_SUB_WRITEA
|
||||
INC HL
|
||||
JR BTLDR_STARTUP_MSG_LOOP
|
||||
BTLDR_INPUT:
|
||||
; Byte 1 & 2 = Length
|
||||
CALL BTLDR_SUB_INPUT_READ
|
||||
LD B, A
|
||||
CALL BTLDR_SUB_INPUT_READ
|
||||
LD C, A
|
||||
|
||||
; Byte 3 & 4 = Offset / Start address
|
||||
CALL BTLDR_SUB_INPUT_READ
|
||||
LD H, A
|
||||
CALL BTLDR_SUB_INPUT_READ
|
||||
LD L, A
|
||||
|
||||
; Byte 5+ = Payload
|
||||
BTLDR_INPUT_1:
|
||||
CALL BTLDR_SUB_INPUT_READ
|
||||
LD (HL),A ;Store byte
|
||||
DEC BC
|
||||
LD A,H
|
||||
OR A.L
|
||||
JR Z, BTLDR_DONE
|
||||
INC HL
|
||||
JR BTLDR_INPUT_1
|
||||
|
||||
BTLDR_DONE:
|
||||
RET
|
||||
|
||||
|
||||
; Strings
|
||||
S_BTLDR_STARTUP_MSG:
|
||||
db "Z8C BTLDR.S V0.1 by Dennis Gunia [RDY] ",0
|
||||
|
||||
|
||||
; Subroutines
|
||||
BTLDR_SUB_WRITEA:
|
||||
OUT (CS_SIO_A_D),A
|
||||
BTLDR_SUB_WRITEA_WAIT:
|
||||
XOR A
|
||||
INC A
|
||||
OUT (CS_SIO_A_C),A
|
||||
IN A,(CS_SIO_A_C)
|
||||
BIT 0,A
|
||||
JR Z, BTLDR_SUB_WRITEA_WAIT
|
||||
RET
|
||||
|
||||
BTLDR_SUB_RTS_OFF:
|
||||
ld a,005h ;write into WR0: select WR5
|
||||
out (CS_SIO_A_C),A
|
||||
ld a,0E8h ;DTR active, TX 8bit, BREAK off, TX on, RTS inactive
|
||||
out (CS_SIO_A_C),A
|
||||
ret
|
||||
BTLDR_SUB_RTS_ON:
|
||||
ld a,005h ;write into WR0: select WR5
|
||||
out (CS_SIO_A_C),A
|
||||
ld a,0EAh ;DTR active, TX 8bit, BREAK off, TX on, RTS active
|
||||
out (CS_SIO_A_C),A
|
||||
ret
|
||||
|
||||
BTLDR_SUB_INPUT_READ:
|
||||
CALL BTLDR_SUB_RTS_ON
|
||||
XOR A
|
||||
OUT (CS_SIO_A_C), a
|
||||
IN A, (CS_SIO_A_C)
|
||||
AND 1
|
||||
JR Z, BTLDR_SUB_INPUT_READ ;LOOP IF BUFFER EMPTY
|
||||
CALL BTLDR_SUB_RTS_OFF
|
||||
IN A, (CS_SIO_A_D)
|
||||
RET
|
||||
136
OperatingSystem/monitor_v2/include/console.s
Normal file
136
OperatingSystem/monitor_v2/include/console.s
Normal file
@@ -0,0 +1,136 @@
|
||||
;DIP SWICTHES
|
||||
;1843200 CLK / x16 SIO CLOCK MODE = 115200
|
||||
;MAX BAUD RATE = 115200
|
||||
;DIP VALUE = 115200/<BAUD>
|
||||
;
|
||||
;9600 -> 12 / 00110000
|
||||
;
|
||||
|
||||
CONSOLE_INIT:
|
||||
CONSOLE_INIT_CTC:
|
||||
;LD A,00001111b ; Set /16 Divider, CPU Trigger, Time COnstant Follows
|
||||
LD A,01001111b ; External Trigger, Time COnstant Follows
|
||||
OUT (CS_CTC_0),A
|
||||
IN A,(CS_DIP) ; Read BAUD from DIP-Switches
|
||||
;LD A,39
|
||||
OUT (CS_CTC_0),A
|
||||
CONSOLE_INIT_SIO:
|
||||
LD A,00110000b ;write into WR0: error reset, select WR0
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,018h ;write into WR0: channel reset
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,004h ;write into WR0: select WR4
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,01000100b ;write into WR4: clkx16,1 stop bit, no parity
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,005h ;write into WR0: select WR5
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,11101000b ;DTR inactive, TX 8bit, BREAK off, TX on, RTS inactive
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,01h ;write into WR0: select WR1
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,00000100b ;no interrupt in CH B, special RX condition affects vect
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,02h ;write into WR0: select WR2
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,0h ;write into WR2: cmd line int vect (see int vec table)
|
||||
;bits D3,D2,D1 are changed according to RX condition
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,003h ;write into WR0: select WR3
|
||||
OUT (CS_SIO_A_C),A
|
||||
LD a,0C1h ;RX 8bit, auto enable off, RX on
|
||||
OUT (CS_SIO_A_C),A
|
||||
;Channel A RX active
|
||||
RET
|
||||
|
||||
; A contains char
|
||||
; Destroys A
|
||||
print_char:
|
||||
push af
|
||||
out (CS_SIO_A_D),a
|
||||
call print_wait_out
|
||||
pop af
|
||||
;call print_char
|
||||
ret
|
||||
; HL contains pointer to string
|
||||
; Destroy A, HL
|
||||
|
||||
print_str:
|
||||
ld a, (hl)
|
||||
or a
|
||||
jr z,print_str_end
|
||||
call print_char
|
||||
inc hl
|
||||
jr print_str
|
||||
print_str_end:
|
||||
ret
|
||||
|
||||
print_clear:
|
||||
ld hl, [MSG_CLEAR]
|
||||
call print_str
|
||||
ret
|
||||
|
||||
print_newLine:
|
||||
ld a,10
|
||||
call print_char
|
||||
ld a,13
|
||||
call print_char
|
||||
ret
|
||||
; destroys a
|
||||
print_wait_out:
|
||||
; check for TX buffer empty
|
||||
sub a ;clear a, write into WR0: select RR0
|
||||
inc a ;select RR1
|
||||
out (CS_SIO_A_C),A
|
||||
in A,(CS_SIO_A_C) ;read RRx
|
||||
bit 0,A
|
||||
jr z,print_wait_out
|
||||
ret
|
||||
|
||||
print_a_hex:
|
||||
push af
|
||||
push bc
|
||||
push de
|
||||
call STRCONV_BYTES_TO_HEX
|
||||
ld a,b
|
||||
call print_char
|
||||
ld a,c
|
||||
call print_char
|
||||
pop de
|
||||
pop bc
|
||||
pop af
|
||||
|
||||
read_char:
|
||||
call A_RTS_ON
|
||||
nop
|
||||
xor a ; a = 0
|
||||
out (CS_SIO_A_C), a ; select reg 0
|
||||
in a, (CS_SIO_A_C) ; read reg 0
|
||||
and 1 ; mask D0 (recieve char available)
|
||||
call A_RTS_OFF
|
||||
ret Z ; return 0 if no char
|
||||
in a, (CS_SIO_A_D) ; read char if avail
|
||||
ret ; return
|
||||
|
||||
;MSG_CRSR_0:
|
||||
; db 0x1B, "[?25h",0
|
||||
;MSG_CRSR_1:
|
||||
; db 0x1B, "[?25l",0
|
||||
MSG_CLEAR:
|
||||
db 27, '[2J', 27, '[H',0
|
||||
|
||||
|
||||
|
||||
; Serial Util Functions
|
||||
A_RTS_OFF:
|
||||
ld a,005h ;write into WR0: select WR5
|
||||
out (CS_SIO_A_C),A
|
||||
ld a,068h ;DTR inactiveh, TX 8bit, BREAK off, TX on, RTS inactive
|
||||
out (CS_SIO_A_C),A
|
||||
ret
|
||||
A_RTS_ON:
|
||||
ld a,005h ;write into WR0: select WR5
|
||||
out (CS_SIO_A_C),A
|
||||
ld a,0EAh ;DTR active, TX 8bit, BREAK off, TX on, RTS active
|
||||
out (CS_SIO_A_C),A
|
||||
ret
|
||||
89
OperatingSystem/monitor_v2/include/conversions.s
Normal file
89
OperatingSystem/monitor_v2/include/conversions.s
Normal file
@@ -0,0 +1,89 @@
|
||||
; HL Contains Address to string
|
||||
; E is 0xFF if error
|
||||
; E is 0x00 if okay
|
||||
; A returns byte
|
||||
; A,DE are destroyed
|
||||
DHEX_TO_BYTE:
|
||||
PUSH HL ;Backup pointer
|
||||
; Load First Byte
|
||||
LD A,(HL) ;Load first char (high)
|
||||
CALL HEX_TO_BIN ;Conv chart to 4bit
|
||||
jr C, DHEX_TO_BYTE_FAILED ;If error jmp to DHEX_TO_BYTE_FAILED
|
||||
SLA A ;shift result to upper 4 bits
|
||||
SLA A
|
||||
SLA A
|
||||
SLA A
|
||||
LD D,A ;store result in D
|
||||
|
||||
INC HL ;next byte
|
||||
LD A,(HL) ;load 2nd char (lower)
|
||||
CALL HEX_TO_BIN ;Conv chart to 4bit
|
||||
jr C, DHEX_TO_BYTE_FAILED ;If error jmp to DHEX_TO_BYTE_FAILED
|
||||
OR D ;merge D with accumulator
|
||||
|
||||
POP HL ;restor original pointer
|
||||
LD E,0x00 ;set error to 0x00 = no error
|
||||
RET
|
||||
DHEX_TO_BYTE_FAILED:
|
||||
LD E,0xFF ;set error to oxFF
|
||||
;LD A,0x00
|
||||
POP HL
|
||||
RET
|
||||
|
||||
; REG A Contains CHAR-Low
|
||||
; If failed, Carry is set
|
||||
HEX_TO_BIN:
|
||||
SUB 48 ; 0 is 0
|
||||
jp PE, HEX_TO_INVALID_2; to low (SUB overflow)
|
||||
CP 10 ; Value is between 0 and 9
|
||||
JR C, HEX_TO_BIN_2
|
||||
SUB 7
|
||||
jp PE, HEX_TO_INVALID_2; to low (SUB overflow)
|
||||
HEX_TO_BIN_2:
|
||||
CP 16
|
||||
JR NC, HEX_TO_INVALID_2; if bigger than 15-> fail
|
||||
AND 0x0F
|
||||
RET
|
||||
HEX_TO_INVALID_2:
|
||||
SCF ;set carry flag
|
||||
RET
|
||||
|
||||
|
||||
;*****************
|
||||
; Convert Byte to Hex Char (ASCII)
|
||||
;*****************
|
||||
;Description: the StrLength function inline
|
||||
;
|
||||
;Inputs: A contains input byte
|
||||
;
|
||||
;Outputs: BC contains 2 Bytes of ASCII (HEX)
|
||||
;
|
||||
;Destroys: A, BC,
|
||||
STRCONV_BYTES_TO_HEX:
|
||||
PUSH AF;Backup A Register
|
||||
RRA
|
||||
RRA
|
||||
RRA
|
||||
RRA
|
||||
CALL STRCONV_BYTES_TO_HEX_1
|
||||
;LD A,D
|
||||
LD B,A
|
||||
POP AF ; Reload first Byte
|
||||
CALL STRCONV_BYTES_TO_HEX_1
|
||||
;LD A,D
|
||||
LD C,A
|
||||
RET
|
||||
|
||||
STRCONV_BYTES_TO_HEX_1:
|
||||
AND 0x0F
|
||||
ADD 48
|
||||
CP 58 ; Check if less than 58 (less than ASCII 9)
|
||||
;JR C, STRCONV_BYTES_TO_HEX_2
|
||||
RET C
|
||||
ADD 7 ; A-F
|
||||
RET
|
||||
STRCONV_BYTES_TO_HEX_2:
|
||||
;LD D,A
|
||||
RET
|
||||
|
||||
|
||||
78
OperatingSystem/monitor_v2/include/debug.s
Normal file
78
OperatingSystem/monitor_v2/include/debug.s
Normal file
@@ -0,0 +1,78 @@
|
||||
|
||||
|
||||
debug_init:
|
||||
ld A,VAR_CONSOLE_CONF ; Setup CTC
|
||||
out (IO_CTC0_C0),A ; Controll word, software reset, time constant follows, CLK/TRG starts timer
|
||||
ld A,VAR_CONSOLE_BAUD ; Setup timer const
|
||||
out (IO_CTC0_C0),A ; Load timer const into CTC (Setup Baud generator)
|
||||
;set up TX and RX:W
|
||||
ld a,00110000b ;write into WR0: error reset, select WR0
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,018h ;write into WR0: channel reset
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,004h ;write into WR0: select WR4
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,04h ;44h write into WR4: clkx1,1 stop bit, no parity
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,005h ;write into WR0: select WR5
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,068h ;DTR active, TX 8bit, BREAK off, TX on, RTS inactive
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,01h ;write into WR0: select WR1
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,00000100b ;no interrupt in CH B, special RX condition affects vect
|
||||
out (IO_SIO0A_C),A
|
||||
;enable SIO channel A RX
|
||||
ld a,003h ;write into WR0: select WR3
|
||||
out (IO_SIO0A_C),A
|
||||
ld a,0C1h ;RX 8bit, auto enable off, RX on
|
||||
out (IO_SIO0A_C),A
|
||||
;Channel A RX active
|
||||
ld hl,[MSG_START_DBG]
|
||||
call debug_print_str
|
||||
ret
|
||||
|
||||
debug_print_char:
|
||||
out (IO_SIO0A_D),a
|
||||
call debug_wait_out
|
||||
ret
|
||||
|
||||
debug_print_str:
|
||||
ld a, (hl)
|
||||
or a
|
||||
ret z
|
||||
call debug_print_char
|
||||
inc hl
|
||||
jr debug_print_str
|
||||
|
||||
debug_print_newLine:
|
||||
ld a,10
|
||||
call debug_print_char
|
||||
ld a,13
|
||||
call debug_print_char
|
||||
ret
|
||||
|
||||
debug_wait_out:
|
||||
; check for TX buffer empty
|
||||
sub a ;clear a, write into WR0: select RR0
|
||||
inc a ;select RR1
|
||||
out (IO_SIO0A_C),A
|
||||
in A,(IO_SIO0A_C) ;read RRx
|
||||
bit 0,A
|
||||
jr z,debug_wait_out
|
||||
ret
|
||||
|
||||
MSG_START_DBG:
|
||||
db "Debug interface active!",13,10,0
|
||||
|
||||
debug_a_hex:
|
||||
push BC
|
||||
push AF
|
||||
call STRCONV_BYTES_TO_HEX
|
||||
ld a, b
|
||||
call debug_print_char
|
||||
ld a, c
|
||||
call debug_print_char
|
||||
pop AF
|
||||
pop BC
|
||||
ret
|
||||
322
OperatingSystem/monitor_v2/include/disassembler copy.s
Normal file
322
OperatingSystem/monitor_v2/include/disassembler copy.s
Normal file
@@ -0,0 +1,322 @@
|
||||
; HL contains start address
|
||||
; B contains length
|
||||
disassemble:
|
||||
call dasm_print16hex_addr ;print address (HL)
|
||||
call disassemble_table_seek
|
||||
xor a
|
||||
or b
|
||||
or c
|
||||
jr z, disassemble_err ;if bc==0000h
|
||||
|
||||
ld a,(hl) ;load first byte
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
call dasm_print8hex ;print value
|
||||
ld a,(hl)
|
||||
cp 0xC3 ;C3 JPnn
|
||||
jp z, dasm_C3
|
||||
|
||||
;start getting value
|
||||
|
||||
disassemble_err:
|
||||
ld a,(hl)
|
||||
call dasm_print8hex ;print value
|
||||
push hl
|
||||
ld hl, [dasm_UU]
|
||||
call print_str
|
||||
pop hl
|
||||
disassemble_continue:
|
||||
call print_newLine
|
||||
inc hl
|
||||
dec b
|
||||
jp nz, disassemble
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;A contains char
|
||||
;BC contains returned position
|
||||
disassemble_table_seek:
|
||||
push hl
|
||||
ld c,a
|
||||
disassemble_table_seek_loop:
|
||||
ld a,(hl)
|
||||
cp c ; if match
|
||||
jr z, disassemble_table_found
|
||||
or a ; if null
|
||||
jp z, disassemble_table_notfound
|
||||
ld b,0
|
||||
ld c,4
|
||||
add hl,bc
|
||||
ld a,(hl)
|
||||
ld c,a
|
||||
add hl,bc
|
||||
inc hl
|
||||
jr disassemble_table_seek_loop
|
||||
|
||||
|
||||
disassemble_table_found
|
||||
ld b,H
|
||||
ld c,l
|
||||
pop hl
|
||||
ret
|
||||
|
||||
disassemble_table_notfound
|
||||
ld b,0
|
||||
ld c,0
|
||||
pop hl
|
||||
ret
|
||||
|
||||
|
||||
|
||||
dasm_C3: ;JP nn (276)
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
ld d, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_C3_str]
|
||||
call print_str
|
||||
ld h,d
|
||||
ld l,e
|
||||
call dasm_print16hex_addr
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_C3_str:
|
||||
db "JP ",0x00
|
||||
|
||||
dasm_JPccnn: ;JP nn (276)
|
||||
rra
|
||||
rra
|
||||
rra
|
||||
and 0x07
|
||||
call dasm_printFlags
|
||||
ld a, ","
|
||||
call print_char
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
ld d, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_C3_str]
|
||||
call print_str
|
||||
ld h,d
|
||||
ld l,e
|
||||
call dasm_print16hex_addr
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
|
||||
dasm_18: ;JR e
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_18_str]
|
||||
call print_str
|
||||
ld a,e
|
||||
call dasm_print8relhex
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_18_str:
|
||||
db "JR ",0x00
|
||||
|
||||
dasm_38: ;JR C,e
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_38_str]
|
||||
call print_str
|
||||
ld a,e
|
||||
call dasm_print8relhex
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_38_str:
|
||||
db "JR C, ",0x00
|
||||
|
||||
dasm_30: ;JR NC,e
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_30_str]
|
||||
call print_str
|
||||
ld a,e
|
||||
call dasm_print8relhex
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_30_str:
|
||||
db "JR NC, ",0x00
|
||||
|
||||
dasm_28: ;JR Z,e
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_28_str]
|
||||
call print_str
|
||||
ld a,e
|
||||
call dasm_print8relhex
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_28_str:
|
||||
db "JR Z, ",0x00
|
||||
|
||||
dasm_20: ;JR NZ,e
|
||||
inc hl
|
||||
ld e, (HL)
|
||||
inc hl
|
||||
;de now has jmp value
|
||||
push hl
|
||||
ld hl, [dasm_20_str]
|
||||
call print_str
|
||||
ld a,e
|
||||
call dasm_print8relhex
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_20_str:
|
||||
db "JR NZ, ",0x00
|
||||
|
||||
dasm_E9: ;JR NZ,e
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_20_str]
|
||||
call print_str
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_E9_str:
|
||||
db "JP (HL), ",0x00
|
||||
|
||||
dasm_E9: ;JP (HL)
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_E9_str]
|
||||
call print_str
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_E9_str:
|
||||
db "JP (HL)",0x00
|
||||
|
||||
dasm_E9: ;JP (IX)
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_E9_str]
|
||||
call print_str
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_E9_str:
|
||||
db "JP (IX)",0x00
|
||||
|
||||
dasm_E9: ;JP (IY)
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_E9_str]
|
||||
call print_str
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_E9_str:
|
||||
db "JP (IY)",0x00
|
||||
|
||||
|
||||
dasm_00: ;JP nn (276)
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_00_str]
|
||||
call print_str
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_00_str:
|
||||
db "NOP",0x00
|
||||
|
||||
dasm_FF: ;JP nn (276)
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_FF_str]
|
||||
call print_str
|
||||
pop hl
|
||||
jp disassemble_continue
|
||||
dasm_FF_str:
|
||||
db "---",0x00
|
||||
|
||||
|
||||
dasm_print16hex_addr:
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,h
|
||||
call print_a_hex
|
||||
ld a,l
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ld a," "
|
||||
call print_char
|
||||
ret
|
||||
|
||||
dasm_print8hex:
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ld a," "
|
||||
call print_char
|
||||
ret
|
||||
|
||||
dasm_print8relhex:
|
||||
push af
|
||||
and 0x80
|
||||
jp nz, dasm_print8relhex_neg
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,"+"
|
||||
call print_char
|
||||
pop af
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ret
|
||||
|
||||
dasm_print8relhex_neg:
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,"-"
|
||||
call print_char
|
||||
pop af
|
||||
neg
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ret
|
||||
|
||||
|
||||
dasm_printFlags:
|
||||
push hl
|
||||
ld hl, [dasm_printFlags_table]
|
||||
rlca
|
||||
ld b,0
|
||||
ld c,a
|
||||
add hl,bc
|
||||
call print_str
|
||||
ld a, " "
|
||||
call print_char
|
||||
pop hl
|
||||
ret
|
||||
|
||||
dasm_printFlags_table:
|
||||
db "NZ",0
|
||||
db "Z",0,0
|
||||
db "NC"
|
||||
db "C",0,0
|
||||
db "PO",0
|
||||
db "PE",0
|
||||
db "P",0,0
|
||||
db "M",0,0
|
||||
569
OperatingSystem/monitor_v2/include/disassembler.s
Normal file
569
OperatingSystem/monitor_v2/include/disassembler.s
Normal file
@@ -0,0 +1,569 @@
|
||||
var_opcode_start equ PRG_RAM_START ;16 bit pointer to opcode in mem
|
||||
var_opcode_table equ PRG_RAM_START+2 ;16 bit pointer to opcode in table
|
||||
var_opcode equ PRG_RAM_START+4 ;8 bit opcode value
|
||||
var_opcode_x equ PRG_RAM_START+5 ;8 bit opcode extension value
|
||||
var_opcode_length equ PRG_RAM_START+6 ;8 bit opcode length (in bytes)
|
||||
var_opcode_string equ PRG_RAM_START+7 ;16 bit pointer to opcode string
|
||||
var_opcode_pcount equ PRG_RAM_START+9 ;8 bit opcode param count
|
||||
var_bytes_count equ PRG_RAM_START+10 ;bytes to examine
|
||||
; HL contains start address
|
||||
; B contains length
|
||||
disassemble:
|
||||
ld a,b
|
||||
ld (var_bytes_count),a
|
||||
disassemble_next:
|
||||
|
||||
|
||||
ld (var_opcode_start), hl ;16 bit pointer to opcode in mem
|
||||
ld a,(hl) ;load opcode to find in A
|
||||
ld (var_opcode), a ;8 bit opcode value
|
||||
inc hl
|
||||
ld a,(hl) ;load opcode to find in A
|
||||
ld (var_opcode_x), a ;8 bit opcode extended value
|
||||
dec hl
|
||||
call disassemble_table_seek
|
||||
ld a,b
|
||||
or c
|
||||
jp z, disassemble_err ;if bc==0000h
|
||||
|
||||
ld (var_opcode_table), bc ;16 bit pointer to opcode in table
|
||||
|
||||
;load params
|
||||
inc bc
|
||||
inc bc
|
||||
inc bc
|
||||
inc bc
|
||||
ld a,(bc)
|
||||
ld (var_opcode_length),A ;8 bit opcode length (in bytes)
|
||||
inc bc
|
||||
ld a, (bc)
|
||||
ld e,a
|
||||
inc bc
|
||||
ld a, (bc)
|
||||
ld d,a
|
||||
ld (var_opcode_string),de ;16 bit pointer to opcode string
|
||||
inc bc
|
||||
ld a,(bc)
|
||||
ld (var_opcode_pcount),A ;8 bit opcode param count
|
||||
|
||||
;values are prepared. Continue with print
|
||||
|
||||
ld hl,(var_opcode_start) ;print address
|
||||
call dasm_print16hex_addr
|
||||
|
||||
ld a,(var_opcode_length)
|
||||
ld b, a
|
||||
|
||||
;print up to 4 opcode bytes
|
||||
ld hl,(var_opcode_start)
|
||||
|
||||
disassemble_print_opcode_raw
|
||||
ld a,(hl) ;load first byte
|
||||
call print_a_hex
|
||||
inc hl
|
||||
djnz disassemble_print_opcode_raw
|
||||
|
||||
ld a,"h"
|
||||
call print_char
|
||||
;fill empty spots
|
||||
ld a,(var_opcode_length)
|
||||
ld b,a
|
||||
ld a,6
|
||||
sub b
|
||||
ld b,a
|
||||
|
||||
disassemble_print_opcode_raw_fill:
|
||||
ld a," "
|
||||
call print_char
|
||||
ld a," "
|
||||
call print_char
|
||||
djnz disassemble_print_opcode_raw_fill
|
||||
ld a," "
|
||||
call print_char
|
||||
|
||||
push hl
|
||||
;print opcode
|
||||
ld hl,(var_opcode_string)
|
||||
call print_str
|
||||
|
||||
|
||||
;print params
|
||||
ld a,(var_opcode_pcount)
|
||||
or a
|
||||
jp z, disassemble_print_opcode_params_end ;skip if no params
|
||||
|
||||
ld hl,(var_opcode_table)
|
||||
ld bc, 8
|
||||
add hl,bc ;hl now has address of first param
|
||||
ld a,(var_opcode_pcount)
|
||||
ld b,a
|
||||
disassemble_print_opcode_params_loop:
|
||||
;ld a,(hl) ;load param
|
||||
;call print_a_hex
|
||||
ld a,(hl) ;load param
|
||||
|
||||
cp 0x01
|
||||
call z, param_01
|
||||
cp 0x02
|
||||
call z, param_02
|
||||
cp 0x03
|
||||
call z, param_03
|
||||
cp 0x04
|
||||
call z, param_04
|
||||
cp 0x05
|
||||
call z, param_05
|
||||
cp 0x06
|
||||
call z, param_06
|
||||
cp 0x07
|
||||
call z, param_07
|
||||
cp 0x08
|
||||
call z, param_08
|
||||
cp 0x09
|
||||
call z, param_09
|
||||
cp 0x10
|
||||
call z, param_10
|
||||
cp 0x11
|
||||
call z, param_11
|
||||
cp 0x12
|
||||
call z, param_12
|
||||
cp 0x13
|
||||
call z, param_13
|
||||
cp 0x0A
|
||||
call z, param_0A
|
||||
;strings
|
||||
cp 0x80
|
||||
call z, param_80
|
||||
cp 0x81
|
||||
call z, param_81
|
||||
inc hl
|
||||
djnz disassemble_print_opcode_params_loop
|
||||
disassemble_print_opcode_params_end:
|
||||
pop hl
|
||||
jr disassemble_continue
|
||||
|
||||
|
||||
disassemble_err:
|
||||
call dasm_print16hex_addr
|
||||
ld a,(hl)
|
||||
call dasm_print8hex ;print value
|
||||
inc hl
|
||||
push hl
|
||||
ld hl, [dasm_UU]
|
||||
call print_str
|
||||
pop hl
|
||||
|
||||
disassemble_continue:
|
||||
|
||||
call print_newLine
|
||||
;inc hl
|
||||
ld a,(var_bytes_count)
|
||||
dec a
|
||||
ld (var_bytes_count),a
|
||||
jp nz, disassemble_next
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;A contains opcode
|
||||
;BC contains returned position
|
||||
disassemble_table_seek:
|
||||
push hl
|
||||
ld hl, [dasm_opcode_table]
|
||||
disassemble_table_seek_loop:
|
||||
ld a,(var_opcode)
|
||||
ld c,a
|
||||
ld a,(hl)
|
||||
cp 0xFF ; if null
|
||||
jp z, disassemble_table_notfound
|
||||
|
||||
;apply mask
|
||||
push af
|
||||
inc hl
|
||||
ld b,(hl) ;load mask
|
||||
dec hl
|
||||
ld a,c
|
||||
and b ;apply mask
|
||||
ld c,a
|
||||
pop af
|
||||
|
||||
cp c ; if match
|
||||
jr z, disassemble_table_first_match
|
||||
ld b,0
|
||||
ld c,7
|
||||
add hl,bc
|
||||
ld a,(hl)
|
||||
ld c,a
|
||||
add hl,bc
|
||||
inc hl
|
||||
jr disassemble_table_seek_loop
|
||||
|
||||
disassemble_table_first_match
|
||||
inc hl
|
||||
inc hl
|
||||
ld c,(hl) ;load opcode x from table
|
||||
inc hl
|
||||
ld a,(var_opcode_x) ;load current opcode x
|
||||
ld b,(hl) ;load mask
|
||||
and b ;apply mask
|
||||
cp c ;compare to table
|
||||
dec hl
|
||||
dec hl
|
||||
dec hl
|
||||
jr z, disassemble_table_found ;IF FOUND
|
||||
ld b,0 ;else continue with next
|
||||
|
||||
ld c,7
|
||||
add hl,bc
|
||||
ld a,(hl)
|
||||
ld c,a
|
||||
add hl,bc
|
||||
inc hl
|
||||
jr disassemble_table_seek_loop
|
||||
|
||||
disassemble_table_found
|
||||
ld b,H
|
||||
ld c,l
|
||||
pop hl
|
||||
ret
|
||||
|
||||
disassemble_table_notfound
|
||||
ld b,0
|
||||
ld c,0
|
||||
pop hl
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
dasm_print16hex_addr:
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,h
|
||||
call print_a_hex
|
||||
ld a,l
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ld a," "
|
||||
call print_char
|
||||
ret
|
||||
|
||||
dasm_print8hex:
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ld a," "
|
||||
call print_char
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
param_01: ; 0x01 16bit address pointer
|
||||
push hl
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
ld a,(de)
|
||||
ld l,a
|
||||
inc de
|
||||
ld a,(de)
|
||||
ld h,a
|
||||
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,h
|
||||
call print_a_hex
|
||||
ld a,l
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
ld a," "
|
||||
call print_char
|
||||
call param_comma
|
||||
pop hl
|
||||
ret
|
||||
|
||||
param_02:
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
ld a,(de)
|
||||
rra
|
||||
rra
|
||||
and 0x0E
|
||||
|
||||
push hl
|
||||
ld hl, [dasm_printFlags_table]
|
||||
ld b,0
|
||||
ld c,a
|
||||
add hl,bc
|
||||
call print_str
|
||||
ld a, " "
|
||||
call print_char
|
||||
pop hl
|
||||
pop bc
|
||||
ret
|
||||
|
||||
|
||||
param_03:
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
ld a,(de)
|
||||
|
||||
push af
|
||||
and 0x80
|
||||
jp nz, param_03_neg
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,"+"
|
||||
call print_char
|
||||
pop af
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
jr param_03_done
|
||||
|
||||
param_03_neg:
|
||||
ld a,"$"
|
||||
call print_char
|
||||
ld a,"-"
|
||||
call print_char
|
||||
pop af
|
||||
neg
|
||||
call print_a_hex
|
||||
ld a,"h"
|
||||
call print_char
|
||||
jr param_03_done
|
||||
|
||||
param_03_done:
|
||||
call param_comma
|
||||
ret
|
||||
|
||||
|
||||
param_04:
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
ld a,(de)
|
||||
cp 0x4D
|
||||
jr z,param_04_i
|
||||
ld a,"N"
|
||||
call print_char
|
||||
ret
|
||||
param_04_i:
|
||||
ld a,"I"
|
||||
call print_char
|
||||
ret
|
||||
|
||||
param_05:
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
ld a,(de)
|
||||
and 0x38
|
||||
; print hex char
|
||||
call dasm_print8hex
|
||||
pop bc
|
||||
ret
|
||||
|
||||
|
||||
param_06:
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
ld a,(de)
|
||||
rra
|
||||
rra
|
||||
rra
|
||||
and 0x07
|
||||
call param_printRegister
|
||||
ld a," "
|
||||
call print_char
|
||||
ld a,","
|
||||
call print_char
|
||||
pop bc
|
||||
ret
|
||||
|
||||
param_07:
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
ld a,(de)
|
||||
and 0x07
|
||||
|
||||
call param_printRegister
|
||||
pop bc
|
||||
ret
|
||||
|
||||
param_08:
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
ld a,(de)
|
||||
call dasm_print8hex
|
||||
pop bc
|
||||
ret
|
||||
|
||||
|
||||
param_0A:
|
||||
push hl
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
inc de
|
||||
jr param_09_0A
|
||||
param_09:
|
||||
push hl
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
param_09_0A:
|
||||
ld a,(de)
|
||||
ld l,a
|
||||
inc de
|
||||
ld a,(de)
|
||||
ld h,a
|
||||
ld a,h
|
||||
call print_a_hex
|
||||
ld a,l
|
||||
call print_a_hex
|
||||
pop hl
|
||||
ret
|
||||
|
||||
param_10:
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
ld a,(de)
|
||||
rra
|
||||
rra
|
||||
rra
|
||||
and 0x07
|
||||
call param_printRegister
|
||||
pop bc
|
||||
ret
|
||||
|
||||
|
||||
param_11:
|
||||
push hl
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
jr param_11_12
|
||||
param_12:
|
||||
push hl
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
inc de
|
||||
|
||||
param_11_12:
|
||||
ld a,(de)
|
||||
rra
|
||||
rra
|
||||
rra
|
||||
and 0x06
|
||||
push af
|
||||
;check which table to use
|
||||
ld hl, (var_opcode_start)
|
||||
ld a,(hl)
|
||||
cp 0xDD
|
||||
jr z,param_11_12_ix
|
||||
cp 0xFD
|
||||
jr z,param_11_12_iy
|
||||
param_11_12_def:
|
||||
ld hl, [dasm_printRegister8_table]
|
||||
jr param_11_12_all
|
||||
param_11_12_ix:
|
||||
ld hl, [dasm_printRegisterIX_table]
|
||||
jr param_11_12_all
|
||||
param_11_12_iy:
|
||||
ld hl, [dasm_printRegisterIY_table]
|
||||
param_11_12_all:
|
||||
pop af
|
||||
ld b,0
|
||||
ld c,a
|
||||
add hl, bc
|
||||
ld a,(hl)
|
||||
call print_char
|
||||
inc hl
|
||||
ld a,(hl)
|
||||
call print_char
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
param_13:
|
||||
push hl
|
||||
push bc
|
||||
ld de,(var_opcode_start)
|
||||
ld a,(de)
|
||||
rra
|
||||
rra
|
||||
rra
|
||||
and 0x06
|
||||
push af
|
||||
;check which table to use
|
||||
ld hl, (var_opcode_start)
|
||||
ld a,(hl)
|
||||
ld hl, [dasm_printRegisterSP_table]
|
||||
jr param_11_12_all ;reuse code from 11_12
|
||||
|
||||
|
||||
param_81:
|
||||
push hl
|
||||
push bc
|
||||
ld hl, (var_opcode_string)
|
||||
ld b,2
|
||||
jr param_80_seek
|
||||
param_80:
|
||||
push hl
|
||||
push bc
|
||||
ld hl, (var_opcode_string)
|
||||
ld b,1
|
||||
param_80_seek:
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
and a
|
||||
jr nz, param_80_seek
|
||||
;found
|
||||
dec b ;found but counter too high
|
||||
jp nz, param_80_seek
|
||||
|
||||
call print_str
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
|
||||
|
||||
param_printRegister:
|
||||
push hl
|
||||
cp 0x06
|
||||
jr z, param_printRegisterHL
|
||||
cp 0x07
|
||||
jr z, param_printRegisterA
|
||||
ld hl, [dasm_printRegister8_table]
|
||||
ld b,0
|
||||
ld c,a
|
||||
add hl,bc
|
||||
ld a, (hl)
|
||||
call print_char
|
||||
pop hl
|
||||
ret
|
||||
|
||||
param_printRegisterHL:
|
||||
ld hl, [dasm_printRegister8_table_HL]
|
||||
call print_str
|
||||
pop hl
|
||||
ret
|
||||
|
||||
param_printRegisterA:
|
||||
ld a,"A"
|
||||
call print_char
|
||||
pop hl
|
||||
ret
|
||||
|
||||
|
||||
param_comma:
|
||||
ld a,b
|
||||
cp 1
|
||||
ret z
|
||||
ld a," "
|
||||
call print_char
|
||||
ld a,","
|
||||
call print_char
|
||||
ret
|
||||
333
OperatingSystem/monitor_v2/include/disassembler_table.s
Normal file
333
OperatingSystem/monitor_v2/include/disassembler_table.s
Normal file
@@ -0,0 +1,333 @@
|
||||
;disassembler tables
|
||||
|
||||
dasm_opcode_table:
|
||||
;byte 0 = opcode
|
||||
;byte 1 = opcode mask
|
||||
;byte 2 = opcode extended
|
||||
;byte 3 = opcode extended mask
|
||||
;byte 4 = length
|
||||
;byte 5+6 = pointer to string
|
||||
;byte 7 = params = count of paramters
|
||||
;byte 8+ = paramters
|
||||
; 0x01 16bit address pointer
|
||||
; 0x02 flag bit 3-5
|
||||
; 0x03 relative jmp address
|
||||
; 0x04 RETI/RETN
|
||||
; 0x05 RST Vector
|
||||
; 0x06 register (r)
|
||||
; 0x07 register (r')
|
||||
; 0x08 8-Bit value
|
||||
; 0x09 16-Bit value
|
||||
; 0x0A 16-bit value with offset +1
|
||||
; 0x10 same as 0x06 without ","
|
||||
; 0x11 print 16 bit register from 1st byte
|
||||
; 0x12 print 16 bit register from 2nd byte
|
||||
; 0x13 push/pop register lookup
|
||||
; 0x80 print string suffix
|
||||
; 0x81 print string suffix 2
|
||||
defb 0x00, 0xFF, 0x00, 0x00, 1, [dasm_00], [dasm_00]>>8,0 ;NOP
|
||||
;General-Purpose Arithmetic and CPU Control Groups
|
||||
defb 0x27, 0xFF, 0x00, 0x00, 1, [dasm_27], [dasm_27]>>8, 0 ;DAA
|
||||
defb 0x2F, 0xFF, 0x00, 0x00, 1, [dasm_2F], [dasm_2F]>>8, 0 ;CPL
|
||||
defb 0xED, 0xFF, 0x44, 0xFF, 2, [dasm_ED_44], [dasm_ED_44]>>8, 0 ;NEG
|
||||
defb 0x3f, 0xFF, 0x00, 0x00, 1, [dasm_3F], [dasm_3F]>>8, 0 ;CCF
|
||||
defb 0x37, 0xFF, 0x00, 0x00, 1, [dasm_37], [dasm_37]>>8, 0 ;SCF
|
||||
;defb 0x00, 0xFF, 0x00, 0x00, 1, [dasm_00], [dasm_00]>>8,0 ;NOP -> already at top for performance reasons
|
||||
defb 0x76, 0xFF, 0x00, 0x00, 1, [dasm_76], [dasm_76]>>8, 0 ;HALT
|
||||
defb 0xF3, 0xFF, 0x00, 0x00, 1, [dasm_F3], [dasm_F3]>>8, 0 ;DI
|
||||
defb 0xFB, 0xFF, 0x00, 0x00, 1, [dasm_FB], [dasm_FB]>>8, 0 ;EI
|
||||
defb 0xED, 0xFF, 0x46, 0xFF, 2, [dasm_ED_46], [dasm_ED_46]>>8, 0 ;IM 0
|
||||
defb 0xED, 0xFF, 0x56, 0xFF, 2, [dasm_ED_56], [dasm_ED_56]>>8, 0 ;IM 1
|
||||
defb 0xED, 0xFF, 0x5E, 0xFF, 2, [dasm_ED_5E], [dasm_ED_5E]>>8, 0 ;IM 2
|
||||
|
||||
;Exchange, Block Transfer, and Search Group
|
||||
defb 0xEB, 0xFF, 0x00, 0x00, 1, [dasm_BE], [dasm_BE]>>8, 0 ;EX DE, HL
|
||||
defb 0x08, 0xFF, 0x00, 0x00, 1, [dasm_08], [dasm_08]>>8, 0 ;EX AF, AF′
|
||||
defb 0xD9, 0xFF, 0x00, 0x00, 1, [dasm_D9], [dasm_D9]>>8, 0 ;EXX
|
||||
defb 0xE3, 0xFF, 0x00, 0x00, 1, [dasm_E3], [dasm_E3]>>8, 0 ;EX (SP), HL
|
||||
defb 0xDD, 0xFF, 0xE3, 0xFF, 2, [dasm_DD_E3], [dasm_DD_E3]>>8, 0 ;EX (SP), IX
|
||||
defb 0xFD, 0xFF, 0xE3, 0xFF, 2, [dasm_FD_E3], [dasm_FD_E3]>>8, 0 ;EX (SP), IY
|
||||
defb 0xED, 0xFF, 0xA0, 0xFF, 2, [dasm_ED_A0], [dasm_ED_A0]>>8, 0 ;LDI
|
||||
defb 0xED, 0xFF, 0xB0, 0xFF, 2, [dasm_ED_B0], [dasm_ED_B0]>>8, 0 ;LDIR
|
||||
defb 0xED, 0xFF, 0xA8, 0xFF, 2, [dasm_ED_A8], [dasm_ED_A8]>>8, 0 ;LDD
|
||||
defb 0xED, 0xFF, 0xB8, 0xFF, 2, [dasm_ED_B8], [dasm_ED_B8]>>8, 0 ;LDDR
|
||||
defb 0xED, 0xFF, 0xA1, 0xFF, 2, [dasm_ED_A1], [dasm_ED_A1]>>8, 0 ;CPI
|
||||
defb 0xED, 0xFF, 0xB1, 0xFF, 2, [dasm_ED_B1], [dasm_ED_B1]>>8, 0 ;CPIR
|
||||
defb 0xED, 0xFF, 0xA9, 0xFF, 2, [dasm_ED_A9], [dasm_ED_A9]>>8, 0 ;CPD
|
||||
defb 0xED, 0xFF, 0xB9, 0xFF, 2, [dasm_ED_B9], [dasm_ED_B9]>>8, 0 ;CPDR
|
||||
|
||||
;JUMP Group
|
||||
defb 0xC3, 0xFF, 0x00, 0x00, 3, [dasm_C3], [dasm_C3]>>8,1, 0x01 ;JP nn
|
||||
defb 0xC2, 0xC7, 0x00, 0x00, 3, [dasm_C3], [dasm_C3]>>8,3, 0x02, 0x80, 0x01 ;JP cc,nn
|
||||
defb 0x18, 0xFF, 0x00, 0x00, 2, [dasm_18], [dasm_18]>>8,1, 0x03 ;JR e
|
||||
defb 0x38, 0xFF, 0x00, 0x00, 2, [dasm_38], [dasm_38]>>8,1, 0x03 ;JR C,e
|
||||
defb 0x30, 0xFF, 0x00, 0x00, 2, [dasm_30], [dasm_30]>>8,1, 0x03 ;JR NC,e
|
||||
defb 0x28, 0xFF, 0x00, 0x00, 2, [dasm_28], [dasm_28]>>8,1, 0x03 ;JR Z,e
|
||||
defb 0x20, 0xFF, 0x00, 0x00, 2, [dasm_20], [dasm_20]>>8,1, 0x03 ;JR NZ,e
|
||||
defb 0xE9, 0xFF, 0x00, 0x00, 2, [dasm_E9], [dasm_E9]>>8,0 ;JP (HL)
|
||||
defb 0xDD, 0xFF, 0xE9, 0xFF, 2, [dasm_DD], [dasm_DD]>>8,0 ;JP (IX)
|
||||
defb 0xFD, 0xFF, 0xE9, 0xFF, 2, [dasm_FD], [dasm_FD]>>8,0 ;JP (IY)
|
||||
defb 0x10, 0xFF, 0x00, 0x00, 2, [dasm_10], [dasm_10]>>8,1, 0x03 ;DJNZ, e
|
||||
;Call and Return Group
|
||||
defb 0xCD, 0xFF, 0x00, 0x00, 3, [dasm_CD], [dasm_CD]>>8,1, 0x01 ;CALL nn
|
||||
defb 0xC4, 0xC7, 0x00, 0x00, 3, [dasm_CD], [dasm_CD]>>8,2, 0x02, 0x01 ;CALL cc,nn
|
||||
defb 0xC9, 0xFF, 0x00, 0x00, 1, [dasm_C9], [dasm_C9]>>8,0 ;RET
|
||||
defb 0xC0, 0xC7, 0x00, 0x00, 1, [dasm_C9], [dasm_C9]>>8,1, 0x02 ;RET cc
|
||||
defb 0xED, 0xFF, 0x4D, 0xFF, 2, [dasm_ED_4D], [dasm_ED_4D]>>8,0 ;RETI
|
||||
defb 0xED, 0xFF, 0x45, 0xFF, 2, [dasm_ED_45], [dasm_ED_45]>>8,0 ;RETN
|
||||
|
||||
defb 0xC7, 0xC7, 0x00, 0x00, 1, [dasm_FF], [dasm_FF]>>8,1, 0x05 ;RST
|
||||
;8-Bit load group
|
||||
defb 0x0A, 0xFF, 0x00, 0x00, 1, [dasm_0A], [dasm_0A]>>8, 0 ;LD A, (BC)
|
||||
defb 0x1A, 0xFF, 0x00, 0x00, 1, [dasm_1A], [dasm_1A]>>8, 0 ;LD A, (DE)
|
||||
defb 0x3A, 0xFF, 0x00, 0x00, 3, [dasm_3A], [dasm_3A]>>8, 2, 0x09, 0x80 ;LD A, (nn)
|
||||
defb 0x02, 0xFF, 0x00, 0x00, 1, [dasm_02], [dasm_02]>>8, 0 ;LD (BC), A
|
||||
defb 0x12, 0xFF, 0x00, 0x00, 1, [dasm_12], [dasm_12]>>8, 0 ;LD (DE), A
|
||||
defb 0x32, 0xFF, 0x00, 0x00, 3, [dasm_32], [dasm_32]>>8, 2, 0x09, 0x80 ;LD (nn), A
|
||||
defb 0xED, 0xFF, 0x57, 0xFF, 2, [dasm__ED_57], [dasm__ED_57]>>8, 0 ;LD A, I
|
||||
defb 0xED, 0xFF, 0x5F, 0xFF, 2, [dasm__ED_5F], [dasm__ED_5F]>>8, 0 ;LD A, R
|
||||
defb 0xED, 0xFF, 0x47, 0xFF, 2, [dasm__ED_47], [dasm__ED_47]>>8, 0 ;LD I, A
|
||||
defb 0xED, 0xFF, 0x4F, 0xFF, 2, [dasm__ED_4F], [dasm__ED_4F]>>8, 0 ;LD R, A
|
||||
|
||||
defb 0x06, 0xC7, 0x00, 0x00, 2, [dasm__LD], [dasm__LD]>>8, 2, 0x06, 0x08 ;LD r, n
|
||||
defb 0x40, 0xC0, 0x00, 0x00, 1, [dasm__LD], [dasm__LD]>>8, 2, 0x06, 0x07 ;LD r, r' / LD r, (HL) / LD (HL), r
|
||||
|
||||
;8-Bit Arithmetic Group
|
||||
defb 0x80, 0xF8, 0x00, 0x00, 1, [dasm_80C6], [dasm_80C6]>>8, 1, 0x07 ;ADD A, r / ADD A, (HL)
|
||||
defb 0xC6, 0xFF, 0x00, 0x00, 2, [dasm_80C6], [dasm_80C6]>>8, 1, 0x08 ;ADD A, n
|
||||
defb 0xDD, 0xFF, 0x86, 0xFF, 3, [dasm_DD_86], [dasm_DD_86]>>8, 2, 0x08, 0x80 ;ADD A, (IX + d)
|
||||
defb 0xFD, 0xFF, 0x86, 0xFF, 3, [dasm_FD_86], [dasm_FD_86]>>8, 2, 0x08, 0x80 ;ADD A, (IY + d)
|
||||
defb 0xC8, 0xF8, 0x00, 0x00, 1, [dasm_C88E], [dasm_C88E]>>8, 1, 0x07 ;ADC A, r / ADC A, (HL)
|
||||
defb 0x8E, 0xF8, 0x00, 0x00, 2, [dasm_C88E], [dasm_C88E]>>8, 1, 0x08 ;ADC A, n
|
||||
defb 0xDD, 0xFF, 0x8E, 0xFF, 3, [dasm_DD_8E], [dasm_DD_8E]>>8, 2, 0x08, 0x80 ;ADC A, (IX + d)
|
||||
defb 0xFD, 0xFF, 0x8E, 0xFF, 3, [dasm_FD_8E], [dasm_FD_8E]>>8, 2, 0x08, 0x80 ;ADC A, (IY + d)
|
||||
defb 0x90, 0xF8, 0x00, 0x00, 1, [dasm__SUB], [dasm__SUB]>>8, 1, 0x07 ;SUB r / SUB A, (HL)
|
||||
defb 0xD6, 0xFF, 0x00, 0x00, 2, [dasm__SUB], [dasm__SUB]>>8, 1, 0x08 ;SUB n
|
||||
defb 0xDD, 0xFF, 0x96, 0xFF, 3, [dasm_DD_96], [dasm_DD_96]>>8, 2, 0x08, 0x80 ;SUB (IX + d)
|
||||
defb 0xFD, 0xFF, 0x96, 0xFF, 3, [dasm_FD_96], [dasm_FD_96]>>8, 2, 0x08, 0x80 ;SUB (IY + d)
|
||||
defb 0x94, 0xF8, 0x00, 0x00, 1, [dasm__SBC], [dasm__SBC]>>8, 1, 0x07 ;SBC A,r / SBC A, (HL)
|
||||
defb 0xDE, 0xFF, 0x00, 0x00, 2, [dasm__SBC], [dasm__SBC]>>8, 1, 0x08 ;SBC A,n
|
||||
defb 0xDD, 0xFF, 0x9E, 0xFF, 3, [dasm_DD_9E], [dasm_DD_9E]>>8, 2, 0x08, 0x80 ;SBC A,(IX + d)
|
||||
defb 0xFD, 0xFF, 0x9E, 0xFF, 3, [dasm_FD_9E], [dasm_FD_9E]>>8, 2, 0x08, 0x80 ;SBC A,(IY + d)
|
||||
defb 0xA0, 0xF8, 0x00, 0x00, 1, [dasm__AND], [dasm__AND]>>8, 1, 0x07 ;AND A,r / AND A, (HL)
|
||||
defb 0xE6, 0xFF, 0x00, 0x00, 2, [dasm__AND], [dasm__AND]>>8, 1, 0x08 ;AND A,n
|
||||
defb 0xDD, 0xFF, 0xA6, 0xFF, 3, [dasm_DD_A6], [dasm_DD_A6]>>8, 2, 0x08, 0x80 ;AND A,(IX + d)
|
||||
defb 0xFD, 0xFF, 0xA6, 0xFF, 3, [dasm_FD_A6], [dasm_FD_A6]>>8, 2, 0x08, 0x80 ;AND A,(IY + d)
|
||||
defb 0xB0, 0xF8, 0x00, 0x00, 1, [dasm__OR], [dasm__OR]>>8, 1, 0x07 ;OR A,r / OR A, (HL)
|
||||
defb 0xF6, 0xFF, 0x00, 0x00, 2, [dasm__OR], [dasm__OR]>>8, 1, 0x08 ;OR A,n
|
||||
defb 0xDD, 0xFF, 0xB6, 0xFF, 3, [dasm_DD_B6], [dasm_DD_B6]>>8, 2, 0x08, 0x80 ;OR A,(IX + d)
|
||||
defb 0xFD, 0xFF, 0xB6, 0xFF, 3, [dasm_FD_B6], [dasm_FD_B6]>>8, 2, 0x08, 0x80 ;OR A,(IY + d)
|
||||
defb 0xA8, 0xF8, 0x00, 0x00, 1, [dasm__XOR], [dasm__XOR]>>8, 1, 0x07 ;XOR A,r / XOR A, (HL)
|
||||
defb 0xEE, 0xFF, 0x00, 0x00, 2, [dasm__XOR], [dasm__XOR]>>8, 1, 0x08 ;XOR A,n
|
||||
defb 0xDD, 0xFF, 0xAE, 0xFF, 3, [dasm_DD_AE], [dasm_DD_AE]>>8, 2, 0x08, 0x80 ;XOR A,(IX + d)
|
||||
defb 0xFD, 0xFF, 0xAE, 0xFF, 3, [dasm_FD_AE], [dasm_FD_AE]>>8, 2, 0x08, 0x80 ;XOR A,(IY + d)
|
||||
defb 0xB8, 0xF8, 0x00, 0x00, 1, [dasm__CP], [dasm__CP]>>8, 1, 0x07 ;CP A,r / CP A, (HL)
|
||||
defb 0xFE, 0xFF, 0x00, 0x00, 2, [dasm__CP], [dasm__CP]>>8, 1, 0x08 ;CP A,n
|
||||
defb 0xDD, 0xFF, 0xBE, 0xFF, 3, [dasm_DD_BE], [dasm_DD_BE]>>8, 2, 0x08, 0x80 ;CP A,(IX + d)
|
||||
defb 0xFD, 0xFF, 0xBE, 0xFF, 3, [dasm_FD_BE], [dasm_FD_BE]>>8, 2, 0x08, 0x80 ;CP A,(IY + d)
|
||||
defb 0x04, 0xC7, 0x00, 0x00, 1, [dasm__INC], [dasm__INC]>>8, 1, 0x10 ;INC r / INC (HL)
|
||||
defb 0xDD, 0xFF, 0x34, 0xFF, 3, [dasm_DD_34], [dasm_DD_34]>>8, 2, 0x08, 0x80 ;INC (IX + d)
|
||||
defb 0xFD, 0xFF, 0x34, 0xFF, 3, [dasm_FD_34], [dasm_FD_34]>>8, 2, 0x08, 0x80 ;INC (IY + d)
|
||||
defb 0x05, 0xC7, 0x00, 0x00, 1, [dasm__DEC], [dasm__DEC]>>8, 1, 0x10 ;DEC r / DEC (HL)
|
||||
defb 0xDD, 0xFF, 0x35, 0xFF, 3, [dasm_DD_35], [dasm_DD_35]>>8, 2, 0x08, 0x80 ;DEC (IX + d)
|
||||
defb 0xFD, 0xFF, 0x35, 0xFF, 3, [dasm_FD_35], [dasm_FD_35]>>8, 2, 0x08, 0x80 ;DEC (IY + d)
|
||||
;16-Bit Arithmetic Group
|
||||
defb 0x09, 0xCF, 0x00, 0x00, 1, [dasm_09], [dasm_09]>>8, 1, 0x11 ;ADD HL, ss
|
||||
defb 0xED, 0xFF, 0x4A, 0xCF, 2, [dasm_ED_4A], [dasm_ED_4A]>>8, 1, 0x12 ;ADC HL, ss
|
||||
defb 0xED, 0xFF, 0x42, 0xCF, 2, [dasm_ED_42], [dasm_ED_42]>>8, 1, 0x12 ;SBC HL, ss
|
||||
defb 0xDD, 0xFF, 0x09, 0xCF, 2, [dasm_DD_09], [dasm_DD_09]>>8, 1, 0x12 ;ADD IX, ss
|
||||
defb 0xFD, 0xFF, 0x09, 0xCF, 2, [dasm_FD_09], [dasm_FD_09]>>8, 1, 0x12 ;ADD IY, ss
|
||||
defb 0x03, 0xCF, 0x00, 0x00, 1, [dasm_03], [dasm_03]>>8, 1, 0x11 ;INC ss
|
||||
defb 0xDD, 0xFF, 0x23, 0xFF, 2, [dasm_DD_23], [dasm_DD_23]>>8, 0 ;INC IX
|
||||
defb 0xFD, 0xFF, 0x23, 0xFF, 2, [dasm_FD_23], [dasm_FD_23]>>8, 0 ;INC IY
|
||||
defb 0x0B, 0xCF, 0x00, 0x00, 1, [dasm_0B], [dasm_0B]>>8, 1, 0x11 ;DEC ss
|
||||
defb 0xDD, 0xFF, 0x2B, 0xFF, 2, [dasm_DD_2B], [dasm_DD_2B]>>8, 0 ;DEC IX
|
||||
defb 0xFD, 0xFF, 0x2B, 0xFF, 2, [dasm_FD_2B], [dasm_FD_2B]>>8, 0 ;DEC IY
|
||||
;16-Bit Load Group
|
||||
defb 0x01, 0xCF, 0x00, 0x00, 3, [dasm_01], [dasm_01]>>8, 3, 0x11, 0x80, 0x09 ;LD dd, nn
|
||||
defb 0xDD, 0xFF, 0x21, 0xFF, 4, [dasm_DD_01], [dasm_DD_01]>>8, 1, 0x0A ;LD IX, nn
|
||||
defb 0xFD, 0xFF, 0x21, 0xFF, 4, [dasm_FD_01], [dasm_FD_01]>>8, 1, 0x0A ;LD IY, nn
|
||||
defb 0x2A, 0xFF, 0x00, 0x00, 3, [dasm_2A], [dasm_2A]>>8, 2, 0x09, 0x80 ;LD HL, (nn)
|
||||
defb 0xED, 0xFF, 0x4B, 0xCF, 4, [dasm_ED_4B], [dasm_ED_4B]>>8, 4, 0x12, 0x80, 0x0A, 0x81 ;LD dd, (nn)
|
||||
defb 0xDD, 0xFF, 0x2A, 0xFF, 4, [dasm_DD_2A], [dasm_DD_2A]>>8, 1, 0x0A ;LD IX, (nn)
|
||||
defb 0xFD, 0xFF, 0x2A, 0xFF, 4, [dasm_FD_2A], [dasm_FD_2A]>>8, 1, 0x0A ;LD IY, (nn)
|
||||
defb 0x22, 0xFF, 0x00, 0x00, 3, [dasm_22], [dasm_22]>>8, 2, 0x0A, 0x80 ;LD (nn), HL
|
||||
defb 0xED, 0xFF, 0x43, 0xCF, 4, [dasm_ED_43], [dasm_ED_43]>>8, 3, 0x0A, 0x80, 0x12 ;LD (nn), dd
|
||||
defb 0xDD, 0xFF, 0x22, 0xCF, 4, [dasm_DD_22], [dasm_DD_22]>>8, 2, 0x0A, 0x80 ;LD (nn), IX
|
||||
defb 0xFD, 0xFF, 0x22, 0xCF, 4, [dasm_FD_22], [dasm_FD_22]>>8, 2, 0x0A, 0x80 ;LD (nn), IY
|
||||
defb 0xF9, 0xFF, 0x00, 0x00, 1, [dasm_F9], [dasm_F9]>>8, 0 ;LD SP, HL
|
||||
defb 0xDD, 0xFF, 0xF9, 0xFF, 2, [dasm_DD_F9], [dasm_DD_F9]>>8, 0 ;LD SP, IX
|
||||
defb 0xFD, 0xFF, 0xF9, 0xFF, 2, [dasm_FD_F9], [dasm_FD_F9]>>8, 0 ;LD SP, IY
|
||||
defb 0xC5, 0xCF, 0x00, 0x00, 1, [dasm_E5], [dasm_E5]>>8, 1, 0x13 ;PUSH qq
|
||||
defb 0xDD, 0xFF, 0xE5, 0xFF, 2, [dasm_DD_E5], [dasm_DD_E5]>>8, 0 ;PUSH IX
|
||||
defb 0xFD, 0xFF, 0xE5, 0xFF, 2, [dasm_FD_E5], [dasm_FD_E5]>>8, 0 ;PUSH IY
|
||||
defb 0xC1, 0xCF, 0x00, 0x00, 1, [dasm_E1], [dasm_E1]>>8, 1, 0x13 ;POP qq
|
||||
defb 0xDD, 0xFF, 0xE1, 0xFF, 2, [dasm_DD_E1], [dasm_DD_E1]>>8, 0 ;POP IX
|
||||
defb 0xFD, 0xFF, 0xE1, 0xFF, 2, [dasm_FD_E1], [dasm_FD_E1]>>8, 0 ;POP IY
|
||||
|
||||
|
||||
dasm_00: db "NOP",0x00
|
||||
;JUMP Group
|
||||
dasm_C3: db "JP ",0x00,", ",0x00
|
||||
dasm_18: db "JR ",0x00
|
||||
dasm_38: db "JR C, ",0x00
|
||||
dasm_30: db "JR NC, ",0x00
|
||||
dasm_28: db "JR Z, ",0x00
|
||||
dasm_20: db "JR NZ, ",0x00
|
||||
dasm_E9: db "JP (HL) ",0x00
|
||||
dasm_DD: db "JP (IX) ",0x00
|
||||
dasm_FD: db "JP (IY) ",0x00
|
||||
dasm_10: db "DJNZ ",0x00
|
||||
;Call and Return Group
|
||||
dasm_CD: db "CALL ",0x00
|
||||
dasm_C9: db "RET ",0x00
|
||||
dasm_ED_4D: db "RETI",0x00
|
||||
dasm_ED_45: db "RETN",0x00
|
||||
dasm_FF: db "RST ",0x00
|
||||
;8-Bit load group
|
||||
dasm_0A: db "LD A,(BC)",0x00
|
||||
dasm_1A: db "LD A,(DE)",0x00
|
||||
dasm_3A: db "LD A,(",0x00, "h)",0x00
|
||||
dasm_02: db "LD (BC), A",0x00
|
||||
dasm_12: db "LD (DE), A",0x00
|
||||
dasm_32: db "LD (",0x00, "h), A",0x00
|
||||
dasm__LD: db "LD ",0x00
|
||||
dasm__ED_57: db "LD A, I",0x00
|
||||
dasm__ED_5F: db "LD A, R",0x00
|
||||
dasm__ED_47: db "LD I, A",0x00
|
||||
dasm__ED_4F: db "LD R, A",0x00
|
||||
;General-Purpose Arithmetic and CPU Control Groups
|
||||
dasm_27: db "DAA",0x00
|
||||
dasm_2F: db "CPL",0x00
|
||||
dasm_ED_44: db "NEG",0x00
|
||||
dasm_3F: db "CCF",0x00
|
||||
dasm_37: db "SCF",0x00
|
||||
dasm_76: db "HALT",0x00
|
||||
dasm_F3: db "DI",0x00
|
||||
dasm_FB: db "EI",0x00
|
||||
dasm_ED_46: db "IM 0",0x00
|
||||
dasm_ED_56: db "IM 1",0x00
|
||||
dasm_ED_5E: db "IM 2",0x00
|
||||
;Exchange, Block Transfer, and Search Group
|
||||
dasm_BE: db "EX DE, HL",0x00
|
||||
dasm_08: db "EX AF, AF′",0x00
|
||||
dasm_D9: db "EXX",0x00
|
||||
dasm_E3: db "EX (SP), HL",0x00
|
||||
dasm_DD_E3: db "EX (SP), IX",0x00
|
||||
dasm_FD_E3: db "EX (SP), IY",0x00
|
||||
dasm_ED_A0: db "LDI",0x00
|
||||
dasm_ED_B0: db "LDIR",0x00
|
||||
dasm_ED_A8: db "LDD",0x00
|
||||
dasm_ED_B8: db "LDDR",0x00
|
||||
dasm_ED_A1: db "CPI",0x00
|
||||
dasm_ED_B1: db "CPIR",0x00
|
||||
dasm_ED_A9: db "CPD",0x00
|
||||
dasm_ED_B9: db "CPDR",0x00
|
||||
;8-Bit Arithmetic Group
|
||||
dasm_80C6: db "ADD A, ", 0x00
|
||||
dasm_DD_86: db "ADD A, (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_86: db "ADD A, (IY+", 0x00, "h)",0x00
|
||||
dasm_C88E: db "ADC A, ", 0x00
|
||||
dasm_DD_8E: db "ADC A, (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_8E: db "ADC A, (IY+", 0x00, "h)",0x00
|
||||
dasm__SUB: db "SUB ", 0x00
|
||||
dasm_DD_96: db "SUB (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_96: db "SUB (IY+", 0x00, "h)",0x00
|
||||
dasm__SBC: db "SBC A, ", 0x00
|
||||
dasm_DD_9E: db "SBC A,(IX+", 0x00, "h)",0x00
|
||||
dasm_FD_9E: db "SBC A,(IY+", 0x00, "h)",0x00
|
||||
dasm__AND: db "AND ", 0x00
|
||||
dasm_DD_A6: db "AND (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_A6: db "AND (IY+", 0x00, "h)",0x00
|
||||
dasm__OR: db "OR ", 0x00
|
||||
dasm_DD_B6: db "OR (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_B6: db "OR (IY+", 0x00, "h)",0x00
|
||||
dasm__XOR: db "XOR ", 0x00
|
||||
dasm_DD_AE: db "XOR (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_AE: db "XOR (IY+", 0x00, "h)",0x00
|
||||
dasm__CP: db "CP ", 0x00
|
||||
dasm_DD_BE: db "CP (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_BE: db "CP (IY+", 0x00, "h)",0x00
|
||||
dasm__INC: db "INC ", 0x00
|
||||
dasm_DD_34: db "INC (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_34: db "INC (IY+", 0x00, "h)",0x00
|
||||
dasm__DEC: db "DEC ", 0x00
|
||||
dasm_DD_35: db "DEC (IX+", 0x00, "h)",0x00
|
||||
dasm_FD_35: db "DEC (IY+", 0x00, "h)",0x00
|
||||
;16-Bit Arithmetic Group
|
||||
dasm_09: db "ADD HL, ",0x00
|
||||
dasm_ED_4A: db "ADC HL, ",0x00
|
||||
dasm_ED_42: db "SBC HL, ",0x00
|
||||
dasm_DD_09: db "ADD IX, ",0x00
|
||||
dasm_FD_09: db "ADD IY, ",0x00
|
||||
dasm_03: db "INC ",0x00
|
||||
dasm_DD_23: db "INC IX, ",0x00
|
||||
dasm_FD_23: db "INC IY, ",0x00
|
||||
dasm_0B: db "DEC ",0x00
|
||||
dasm_DD_2B: db "DEC IX, ",0x00
|
||||
dasm_FD_2B: db "DEC IY, ",0x00
|
||||
;16-Bit Load Group
|
||||
dasm_01: db "LD ",0x00, ", ",0x00
|
||||
dasm_DD_01: db "LD IX, ",0x00
|
||||
dasm_FD_01: db "LD IY, ",0x00
|
||||
dasm_2A: db "LD HL, (",0x00,"h)",0x00
|
||||
dasm_ED_4B: db "LD ",0x00,", (",0x00,"h)",0x00
|
||||
dasm_DD_2A: db "LD IX, (",0x00,"h)",0x00
|
||||
dasm_FD_2A: db "LD IY, (",0x00,"h)",0x00
|
||||
dasm_22: db "LD (",0x00,"h), HL",0x00
|
||||
dasm_ED_43: db "LD (",0x00,"h), ",0x00
|
||||
dasm_DD_22: db "LD (",0x00,"h), IX",0x00
|
||||
dasm_FD_22: db "LD (",0x00,"h), IY",0x00
|
||||
dasm_F9: db "LD SP, HL",0x00
|
||||
dasm_DD_F9: db "LD SP, IX",0x00
|
||||
dasm_FD_F9: db "LD SP, IY",0x00
|
||||
dasm_E5: db "PUSH ",0x00
|
||||
dasm_DD_E5: db "PUSH IX",0x00
|
||||
dasm_FD_E5: db "PUSH IY",0x00
|
||||
dasm_E1: db "PUSH ",0x00
|
||||
dasm_DD_E1: db "PUSH IX",0x00
|
||||
dasm_FD_E1: db "PUSH IY",0x00
|
||||
|
||||
;Misc
|
||||
dasm_UU: db ".?.",0x00
|
||||
dasm_UW: db " ",0x00
|
||||
|
||||
dasm_printFlags_table:
|
||||
db "NZ"
|
||||
db "Z",0
|
||||
db "NC"
|
||||
db "C",0
|
||||
db "PO"
|
||||
db "PE"
|
||||
db "P",0
|
||||
db "M",0
|
||||
|
||||
dasm_printRegister8_table:
|
||||
db "B"
|
||||
db "C"
|
||||
db "D"
|
||||
db "E"
|
||||
db "H"
|
||||
db "L"
|
||||
db "S" ;only 18 bit (SP)
|
||||
db "P" ;only 18 bit (SP)
|
||||
|
||||
dasm_printRegisterIX_table:
|
||||
db "BC"
|
||||
db "DE"
|
||||
db "IX"
|
||||
db "SP"
|
||||
dasm_printRegisterIY_table:
|
||||
db "BC"
|
||||
db "DE"
|
||||
db "IY"
|
||||
db "SP"
|
||||
|
||||
dasm_printRegisterSP_table:
|
||||
db "BC"
|
||||
db "DE"
|
||||
db "HL"
|
||||
db "AF"
|
||||
|
||||
dasm_printRegister8_table_HL:
|
||||
db "(HL)", 0
|
||||
158
OperatingSystem/monitor_v2/include/keyboard.s
Normal file
158
OperatingSystem/monitor_v2/include/keyboard.s
Normal file
@@ -0,0 +1,158 @@
|
||||
;----------------------------------------------------------------
|
||||
;Keyboard input library for Z8C
|
||||
;by Dennis Gunia (04/2022)
|
||||
;----------------------------------------------------------------
|
||||
|
||||
var_ps2_extension equ var_ps2mem+4 ;extension code
|
||||
var_ps2_shift equ var_ps2mem+5 ;shift down = 0xFF, up = 0x00
|
||||
var_ps2_raw equ var_ps2mem+6 ;raw scan code
|
||||
|
||||
keybd_read:
|
||||
xor a
|
||||
ld (var_ps2_extension), a
|
||||
call keybd_read_wait
|
||||
cp 0xE0
|
||||
jr z, keybd_read_extended ;handle extended scancodes
|
||||
cp 0xE1
|
||||
jr z, keybd_read_extended_E1 ;handle extended scancodes for stupid pause button ....
|
||||
;else fall through to keybd_read_simple
|
||||
|
||||
keybd_read_simple:
|
||||
cp 0xF0 ;check if break
|
||||
jr z, keybd_read_break ;handle break code logic
|
||||
cp 0x12
|
||||
jr z, keybd_shift_down
|
||||
cp 0x59
|
||||
jr z, keybd_shift_down
|
||||
;else process key
|
||||
jr keybd_read_return
|
||||
|
||||
keybd_read_extended:
|
||||
ld (var_ps2_extension), a ;store first byte to ram
|
||||
call keybd_read_wait ;read key
|
||||
cp 0xF0 ;check if break
|
||||
jr z, keybd_read_break_extended ;handle break code logic
|
||||
;else process key
|
||||
jr keybd_read_return
|
||||
|
||||
keybd_read_extended_E1: ;pause key
|
||||
call keybd_read_wait ;read realeased key
|
||||
call keybd_read_wait ;read realeased key
|
||||
call keybd_read_wait ;read realeased key
|
||||
call keybd_read_wait ;read realeased key
|
||||
call keybd_read_wait ;read realeased key
|
||||
call keybd_read_wait ;read realeased key
|
||||
;fall-thorugh for last byte
|
||||
keybd_read_break_extended:
|
||||
call keybd_read_wait ;read realeased key
|
||||
jr keybd_read
|
||||
|
||||
keybd_read_break:
|
||||
call keybd_read_wait ;read realeased key
|
||||
cp 0x12
|
||||
jr z, keybd_shift_up
|
||||
cp 0x59
|
||||
jr z, keybd_shift_up
|
||||
jp keybd_read
|
||||
|
||||
keybd_read_return:
|
||||
;a contains scan code
|
||||
ret
|
||||
|
||||
|
||||
keybd_shift_down:
|
||||
ld a,0x01
|
||||
ld (var_ps2_shift),a
|
||||
jr keybd_read
|
||||
keybd_shift_up:
|
||||
xor a
|
||||
ld (var_ps2_shift),a
|
||||
jr keybd_read
|
||||
|
||||
|
||||
;wait for keyboard input
|
||||
keybd_read_wait:
|
||||
call keyboard_read
|
||||
jr z, keybd_read_wait ;read again if error
|
||||
ret
|
||||
|
||||
|
||||
keybd_read_ascii:
|
||||
call keybd_read
|
||||
;push af
|
||||
;call print_a_hex
|
||||
;pop af
|
||||
|
||||
ld ix, [keybd_lut] ;LUT base address
|
||||
ld bc, 4 ;increments
|
||||
ld d, a ;Load scancode into d
|
||||
keybd_read_ascii_seekloop:
|
||||
ld a, (ix) ;load scancode from table
|
||||
or a ;test if scancode is 0x00 -> indicates end of list
|
||||
jr z, keybd_read_ascii_notfound ;reached end of list wizhout match
|
||||
cp d ;compare scancode
|
||||
jr z, keybd_read_ascii_match ;found entry
|
||||
add ix,bc
|
||||
jr keybd_read_ascii_seekloop
|
||||
|
||||
keybd_read_ascii_match:
|
||||
ld b,0
|
||||
ld a, (var_ps2_shift) ;if shift offset+1
|
||||
inc a ;add ofset for column1
|
||||
ld c,a
|
||||
add ix,bc ;add column address to row address
|
||||
ld a,(ix)
|
||||
ret
|
||||
|
||||
keybd_read_ascii_notfound:
|
||||
jr keybd_read_ascii
|
||||
|
||||
keybd_lut:
|
||||
defb 0x1C, "a", "A", "@"
|
||||
defb 0x32, "b", "B", 0x00
|
||||
defb 0x21, "c", "C", 0x00
|
||||
defb 0x23, "d", "D", 0x00
|
||||
defb 0x24, "e", "E", 0x00
|
||||
defb 0x2B, "f", "F", 0x00
|
||||
defb 0x34, "g", "G", 0x00
|
||||
defb 0x33, "h", "H", 0x00
|
||||
defb 0x43, "i", "I", 0x00
|
||||
defb 0x3B, "j", "J", 0x00
|
||||
defb 0x42, "k", "K", 0x00
|
||||
defb 0x4B, "l", "L", 0x00
|
||||
defb 0x3A, "m", "M", 0x00
|
||||
defb 0x31, "n", "N", 0x00
|
||||
defb 0x44, "o", "O", 0x00
|
||||
defb 0x4D, "p", "P", 0x00
|
||||
defb 0x15, "q", "Q", 0x00
|
||||
defb 0x2D, "r", "R", 0x00
|
||||
defb 0x1B, "s", "S", 0x00
|
||||
defb 0x2C, "t", "T", 0x00
|
||||
defb 0x3C, "u", "U", 0x00
|
||||
defb 0x2A, "v", "V", 0x00
|
||||
defb 0x1D, "w", "W", 0x00
|
||||
defb 0x22, "x", "X", 0x00
|
||||
defb 0x1A, "y", "Y", 0x00
|
||||
defb 0x35, "z", "Z", 0x00
|
||||
defb 0x45, "0", "=", "}"
|
||||
defb 0x16, "1", "!", 0x00
|
||||
defb 0x1E, "2", 0x22, 0x00
|
||||
defb 0x26, "3", "3", 0x00
|
||||
defb 0x25, "4", "$", 0x00
|
||||
defb 0x2E, "5", "%", 0x00
|
||||
defb 0x36, "6", "&", 0x00
|
||||
defb 0x3D, "7", "/", "{"
|
||||
defb 0x3E, "8", "(", "["
|
||||
defb 0x46, "9", ")", "]"
|
||||
defb 0x41, ",", ";", 0x00
|
||||
defb 0x49, ".", ":", 0x00
|
||||
defb 0x4A, "-", "_", 0x00
|
||||
defb 0x5D, "#", "'", 0x00
|
||||
defb 0x5B, "+", "*", "~"
|
||||
defb 0x4E, "s", "?", 0x5C
|
||||
defb 0x61, "<", ">", "|"
|
||||
defb 0x5A, 13, 13, 13 ;enter
|
||||
defb 0x66, 0x08, 0x08, 0x08 ;backspace
|
||||
defb 0x29, " ", " ", 0x00 ;space
|
||||
defb 0x00 ;end of LUT
|
||||
|
||||
16
OperatingSystem/monitor_v2/include/parity.s
Normal file
16
OperatingSystem/monitor_v2/include/parity.s
Normal file
@@ -0,0 +1,16 @@
|
||||
; a contains data
|
||||
; bc destroied
|
||||
; carry is set if odd, reset if even
|
||||
calc_parity:
|
||||
ld c,0 ;parity data
|
||||
ld b,8 ;bit counter
|
||||
calc_parity_loop:
|
||||
rrca
|
||||
jr nc,calc_parity_loop_2 ;if not zero then skip increment
|
||||
inc c
|
||||
calc_parity_loop_2:
|
||||
djnz calc_parity_loop
|
||||
ld a,c
|
||||
rra ;carry is set to bit 0 of high-counter.
|
||||
;if bit1 is set -> odd # of 1s else even # of 1s
|
||||
ret
|
||||
22
OperatingSystem/monitor_v2/include/rst.s
Normal file
22
OperatingSystem/monitor_v2/include/rst.s
Normal file
@@ -0,0 +1,22 @@
|
||||
EXEC_RST_08:
|
||||
call print_char
|
||||
ret
|
||||
|
||||
|
||||
EXEC_RST_10:
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
;call vdp_cursor_on
|
||||
call read_char
|
||||
push af
|
||||
;call vdp_cursor_off
|
||||
pop af
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
EXEC_RST_18:
|
||||
ld a,0
|
||||
ret
|
||||
96
OperatingSystem/monitor_v2/include/vt82c42.s
Normal file
96
OperatingSystem/monitor_v2/include/vt82c42.s
Normal file
@@ -0,0 +1,96 @@
|
||||
;----------------------------------------------------------------
|
||||
;Keyboard interface driver for Z8C
|
||||
;Controller used: vt82c42
|
||||
;Datasheet: http://www.s100computers.com/My%20System%20Pages/MSDOS%20Board/vt82c42%20PC%20Keyboard%20conrtroller.pdf
|
||||
;by Dennis Gunia (04/2022)
|
||||
;----------------------------------------------------------------
|
||||
|
||||
;IO Ports
|
||||
CS_VT82C42_DATA .EQU F0h
|
||||
CS_VT82C42_CTRL .EQU F1h
|
||||
|
||||
keyboard_init_io: ;Subroutine for initializing keyboard controller
|
||||
LD A, A7h ;Disable Mouse
|
||||
OUT (CS_VT82C42_CTRL), A
|
||||
LD A, ADh ;Disable Keyboard
|
||||
OUT (CS_VT82C42_CTRL), A
|
||||
_keyboard_init_flush_buffer:
|
||||
IN A,(CS_VT82C42_DATA) ;Read buffer
|
||||
IN A,(CS_VT82C42_CTRL) ;Read status byte
|
||||
BIT 0,A ;Test if buffer is empty
|
||||
JR Z, _keyboard_init_flush_buffer
|
||||
;buffer is now flushed. Now set the Controller Configuration Byte
|
||||
IN A,(CS_VT82C42_CTRL) ;Disable bits 0,1,6 (disablee IRQ and Translation)
|
||||
AND 10111100
|
||||
OUT (CS_VT82C42_CTRL),A
|
||||
;Perform Controller Self Test
|
||||
LD A, AAh
|
||||
OUT (CS_VT82C42_CTRL), A
|
||||
NOP
|
||||
IN A,(CS_VT82C42_CTRL) ;Check results
|
||||
CP 55h
|
||||
JR NZ, keyboard_init_failed
|
||||
;Perform Interface Tests
|
||||
LD A, ABh
|
||||
OUT (CS_VT82C42_CTRL), A
|
||||
NOP
|
||||
IN A,(CS_VT82C42_CTRL) ;Check results
|
||||
CP 00h
|
||||
JR NZ, _keyboard_init_failed
|
||||
;Enable Devices
|
||||
LD A,AEh
|
||||
OUT (CS_VT82C42_CTRL), A
|
||||
;Reset Devices
|
||||
LD A,FFh
|
||||
OUT (CS_VT82C42_DATA), A ;Send reset to keboard (0xFF command)
|
||||
NOP
|
||||
IN A,(CS_VT82C42_CTRL) ;Read status byte
|
||||
BIT 0,A ;Test if buffer is empty -> no keyboard found
|
||||
JP NZ, _keyboard_init_dev_missing
|
||||
CP A, 0xFC
|
||||
JR Z, _keyboard_init_okay ; 0xFC -> Success. Init done!
|
||||
;Else device error
|
||||
LD HL, [STR_keyboard_init_failed]
|
||||
CALL print_str
|
||||
HALT
|
||||
_keyboard_init_failed:
|
||||
LD HL, [STR_keyboard_init_err]
|
||||
CALL print_str
|
||||
HALT
|
||||
_keyboard_init_dev_missing:
|
||||
LD HL, [STR_keyboard_init_missing]
|
||||
CALL print_str
|
||||
HALT
|
||||
_keyboard_init_okay:
|
||||
LD HL, [STR_keyboard_init_okay]
|
||||
CALL print_str
|
||||
RET
|
||||
|
||||
;Keyboard IO functions
|
||||
keyboard_read:
|
||||
IN A,(CS_VT82C42_CTRL) ;Read status byte
|
||||
BIT 0,A ;Test if buffer is empty
|
||||
RET NZ ;Return if empty
|
||||
IN A,(CS_VT82C42_DATA)
|
||||
RET ;Return with data in A
|
||||
|
||||
keyboard_write:
|
||||
PUSH AF
|
||||
_keyboard_write_wait:
|
||||
IN A,(CS_VT82C42_CTRL) ;Read status byte
|
||||
BIT 1,A ;Test if buffer is full
|
||||
JR Z, _keyboard_write_wait ;Wait if input buffer is full
|
||||
POP AF
|
||||
OUT (CS_VT82C42_DATA), A
|
||||
RET
|
||||
|
||||
|
||||
;Status message strings
|
||||
STR_keyboard_init_okay:
|
||||
.BYTE "PS/2 Keyboard initialized.",0
|
||||
STR_keyboard_init_err:
|
||||
.BYTE "PS/2 Controller error! System HALT!",0
|
||||
STR_keyboard_init_failed:
|
||||
.BYTE "PS/2 Keyboard error! System HALT!",0
|
||||
STR_keyboard_init_missing:
|
||||
.BYTE "PS/2 no keyboard found!",0
|
||||
286
OperatingSystem/monitor_v2/include/xmodem.s
Normal file
286
OperatingSystem/monitor_v2/include/xmodem.s
Normal file
@@ -0,0 +1,286 @@
|
||||
;-------------------------------------------------------------------------
|
||||
; Z80 XMODEM implementation by Dennis Gunia
|
||||
; 2022 - www,dennisgunia.de
|
||||
;
|
||||
; important doc: https://web.mit.edu/6.115/www/amulet/xmodem.htm
|
||||
; http://www.blunk-electronic.de/train-z/pdf/xymodem.pdf
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
;Symbols
|
||||
SYM_SOH equ 0x01
|
||||
SYM_EOT equ 0x04
|
||||
SYM_ACK equ 0x06
|
||||
SYM_NAK equ 0x15
|
||||
SYM_ETB equ 0x17
|
||||
SYM_CAN equ 0x18
|
||||
SYM_C equ 0x43
|
||||
|
||||
;Memory locations
|
||||
MEM_VAR_BLOCK equ 0x40FB ;last block
|
||||
MEM_VAR_TIMEA equ 0x40FC ;timer var (mills)
|
||||
MEM_VAR_TIMER equ 0x40FE ;timer var (seconds)
|
||||
MEM_INT_VEC_T equ 0x40FE ;interrupt vector table
|
||||
|
||||
MEM_LOC_LOAD equ 0x4400 ;load location for program
|
||||
|
||||
;XMODEM routine
|
||||
xmodem_init:
|
||||
call A_RTS_OFF
|
||||
|
||||
LD A,10100111b ; Init CTC Channel 3
|
||||
OUT (CS_CTC_2),A
|
||||
LD A,14 ; 1028.57Hz ISR
|
||||
OUT (CS_CTC_2),A
|
||||
LD A,00h ; Set CTC Ch3 Interrupt Vector
|
||||
OUT (CS_CTC_0),A
|
||||
;load int vector to ram
|
||||
ld hl,xmodem_int ;CTC Ch3 INT routine
|
||||
ld (0x4200 + 0x04),hl
|
||||
;reset timer vars
|
||||
ld hl,0x0000
|
||||
ld (MEM_VAR_TIMEA),hl
|
||||
ld (MEM_VAR_TIMER),hl
|
||||
|
||||
ld a,0x42 ; Set interrupt vector register
|
||||
ld i,a
|
||||
im 2 ; Z80 Interrupt mode
|
||||
|
||||
ld hl,MSG_START ; Print start banner
|
||||
call print_str
|
||||
ei ; Enable interrupts
|
||||
; init done. Continue with xmodem_await_conn
|
||||
call xmodem_wait
|
||||
|
||||
xmodem_await_conn: ;Wait for initial connection
|
||||
ld a, SYM_C ;Send C to notify sender, that we want CRC
|
||||
call xmodem_out
|
||||
call xmodem_read_wait ;Read with timeout
|
||||
jp c, xmodem_await_conn ;Carry flag set = timeout -> repeat
|
||||
;else continue
|
||||
|
||||
xmodem_packet: ;XmodemCRC packet start
|
||||
;use 1st byte to decide further processing
|
||||
cp SYM_EOT ;End of Transmission
|
||||
jp z, xmodem_packet_EOT
|
||||
cp SYM_CAN ;Cancel (Force receiver to start sending C's)
|
||||
jp z, xmodem_await_conn
|
||||
cp SYM_SOH ;Start of
|
||||
jp z, xmodem_packet_get
|
||||
|
||||
jp xmodem_err ;anything else is an error -> abort transmission
|
||||
|
||||
xmodem_packet_get: ;if first byte == SYM_SOH -> receive block
|
||||
call xmodem_read_wait ;get byte 2 => block ID
|
||||
jp c, xmodem_nak
|
||||
ld b,a
|
||||
ld (MEM_VAR_BLOCK), a ;store block id to memory
|
||||
call xmodem_read_wait ;get byte 3 => block ID complement
|
||||
jp c, xmodem_nak
|
||||
add b
|
||||
cp 255 ;both size infos should always sum to 255
|
||||
jp nz,xmodem_err ;if not 255 then its an error
|
||||
|
||||
;calculate block start address in RAM
|
||||
;multiply by 128
|
||||
;use more efficient bit-wise operations
|
||||
dec a ;a-1 to remove 1 sector offset
|
||||
ld a,b
|
||||
rra ;shift 1 bit to the right
|
||||
and 0x7F
|
||||
ld h,a
|
||||
ld a,b
|
||||
dec a ;a-1 to remove 1 sector offset
|
||||
rrca ;shift bit0 to bit 7
|
||||
and 0x80 ;mask out all other bits
|
||||
ld l,a
|
||||
;result:
|
||||
;hl = 0aaaaaaa a000000
|
||||
|
||||
ld de,MEM_LOC_LOAD
|
||||
add hl,de ;add calculated offset to base address
|
||||
;hl now contains the true start address of this sector
|
||||
|
||||
ld b,128 ;preload counter for data baytes
|
||||
ld c,0 ;packet length counter ( used for overflow error )
|
||||
|
||||
xmodem_packet_get_data: ;get 128 data bytes (loop)
|
||||
push hl ;push hl onto stack because xmodem_read_wait destroys hl
|
||||
call xmodem_read_wait ;read byte or timeout
|
||||
jp c, xmodem_nak ;if timeout -> nak and retry
|
||||
pop hl ;restore hl
|
||||
ld (hl), a ;store received byte in memory
|
||||
inc hl ;increment pointer
|
||||
inc c ;increment packet length counter
|
||||
dec b ;decerment data bytes remmaining
|
||||
jp nz, xmodem_packet_get_data ;if bytes remaining, loop
|
||||
;else continue with crc bytes
|
||||
|
||||
xmodem_packet_get_crc: ;get 16-Bit CRC
|
||||
call xmodem_read_wait
|
||||
jp c, xmodem_nak
|
||||
ld d,a
|
||||
inc c
|
||||
call xmodem_read_wait
|
||||
jp c, xmodem_nak
|
||||
ld e,a
|
||||
inc c
|
||||
;de now contains CRC value
|
||||
;check if c is not bigger than 130 byte (128 data + 2crc)
|
||||
;TODO if so NACK
|
||||
|
||||
;de contains 16-bit CRC
|
||||
;TODO if crc error NACK
|
||||
jp xmodem_ack ;ack block -> then jump to start again
|
||||
|
||||
xmodem_packet_EOT: ;End of transmission SUB.
|
||||
ld a, SYM_ACK ;Acknowledge EOT
|
||||
call xmodem_out
|
||||
jp xmodem_end ;and end xmodem
|
||||
|
||||
|
||||
|
||||
xmodem_err: ;non recoverable error -> abort
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
call xmodem_out
|
||||
ld a, SYM_CAN
|
||||
|
||||
ld hl, MSG_ERROR
|
||||
call print_str
|
||||
|
||||
;overflow to end
|
||||
xmodem_end:
|
||||
di ;disable interrupts
|
||||
call print_newLine ;print new line
|
||||
jp PROMPT_BEGIN ;return ti prompt
|
||||
|
||||
;isr is used as counter for timeouts
|
||||
xmodem_int:
|
||||
di ;setup ISR (disable further interrupts, exchange registers)
|
||||
ex AF,AF'
|
||||
exx
|
||||
|
||||
ld hl,(MEM_VAR_TIMEA) ;millis counter
|
||||
inc hl
|
||||
ld (MEM_VAR_TIMEA),hl
|
||||
|
||||
ld de,1028 ;every 1028 millis counter
|
||||
sbc hl,de
|
||||
jp nz, xmodem_int_cont ;if less than 1028 millis, loop
|
||||
|
||||
ld hl,0 ;reset millis
|
||||
ld (MEM_VAR_TIMEA),hl
|
||||
ld hl,(MEM_VAR_TIMER) ;incement seconds
|
||||
inc hl
|
||||
ld (MEM_VAR_TIMER),hl
|
||||
xmodem_int_cont: ;end isr
|
||||
ex AF,AF' ;restore registers
|
||||
exx
|
||||
EI ;enable interrupts
|
||||
reti ;exit ISR
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; A returns char
|
||||
; Carry is set if timeout
|
||||
xmodem_read_timeount equ 3 ;3 seconds timeout
|
||||
xmodem_read_wait:
|
||||
di
|
||||
ld hl,0
|
||||
ld (MEM_VAR_TIMEA),hl
|
||||
ld (MEM_VAR_TIMER),hl
|
||||
ei
|
||||
call A_RTS_ON
|
||||
xmodem_read_wait_loop:
|
||||
;check timeout
|
||||
ld hl,(MEM_VAR_TIMER)
|
||||
ld a, l
|
||||
cp xmodem_read_timeount
|
||||
jp z, xmodem_read_wait_timeout ;if timeout retry
|
||||
|
||||
; if no timeout
|
||||
xor a ; a = 0
|
||||
out (CS_SIO_A_C), a ; select reg 0
|
||||
in a, (CS_SIO_A_C) ; read reg 0
|
||||
and 1 ; mask D0 (recieve char available)
|
||||
jp Z,xmodem_read_wait_loop ; wait if no char
|
||||
|
||||
; if char avail
|
||||
in a, (CS_SIO_A_D) ; read char
|
||||
;call debug_a_hex
|
||||
push af
|
||||
call A_RTS_OFF
|
||||
pop af
|
||||
scf
|
||||
ccf
|
||||
ret ; return
|
||||
xmodem_read_wait_timeout:
|
||||
scf
|
||||
ret
|
||||
|
||||
|
||||
xmodem_out:
|
||||
out (CS_SIO_A_D), a
|
||||
call xmodem_wait_out
|
||||
ret
|
||||
|
||||
xmodem_wait_out:
|
||||
sub a ;clear a, write into WR0: select RR0
|
||||
inc a ;select RR1
|
||||
out (CS_SIO_A_C),A
|
||||
in A,(CS_SIO_A_C) ;read RRx
|
||||
bit 0,A
|
||||
jr z,xmodem_wait_out
|
||||
ret
|
||||
|
||||
MSG_ERROR:
|
||||
db "Error: unexpected byte",13,10,0
|
||||
|
||||
MSG_START:
|
||||
db "Await xmodem connection",13,10,0
|
||||
|
||||
|
||||
xmodem_ack: ;ack routine. Only use when expecting transmission afterwards.
|
||||
ld a, SYM_ACK ;send ACK
|
||||
call xmodem_out
|
||||
call xmodem_read_wait ;wait for response
|
||||
jp c, xmodem_ack ;if timeout repeat
|
||||
jp xmodem_packet ;if received, continue with new packet
|
||||
|
||||
xmodem_nak: ;nak routine. Only use when expecting transmission afterwards.
|
||||
ld a, SYM_NAK ;send NAK
|
||||
call xmodem_out
|
||||
call xmodem_read_wait ;wait for response
|
||||
jp c, xmodem_nak ;if timeout repeat
|
||||
jp xmodem_packet ;if received, continue with new packet
|
||||
|
||||
xmodem_wait:
|
||||
ld hl, 0xFF
|
||||
ld bc, 0x01
|
||||
xmodem_wait_1:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
sbc hl,bc
|
||||
ret Z
|
||||
jr xmodem_wait_1
|
||||
Reference in New Issue
Block a user