mirror of
https://github.com/Tolik-Trek/Estex-DSS.git
synced 2026-08-05 01:34:39 +03:00
Пока не работает, надо доделывать BigDir.
Затащены правки из Master: Исправлен баг с относительными путями. thx to @witchcraft2001 IF, GOTO, GOSUB/RETURN in BAT files. Правки CLP -bug с выводом строки в BAT -bug M_INT: RFI is CH-A ONLY (per Z80 SIO spec) -bug KEYINTER.ASM: russian chars fix Num Lock numbers
This commit is contained in:
parent
4423f41f1a
commit
41ff458cd4
@ -155,6 +155,7 @@ EX_PATH: EXX
|
|||||||
.NAME_YEP: LD A,2
|
.NAME_YEP: LD A,2
|
||||||
CP C
|
CP C
|
||||||
JR Z,.NOFNAME
|
JR Z,.NOFNAME
|
||||||
|
;
|
||||||
PUSH HL
|
PUSH HL
|
||||||
LD HL,TMPBUF
|
LD HL,TMPBUF
|
||||||
LD DE,(NM_NAME) ; ¤à¥á ¡ãä¥à ¯®¤ ¨¬ï ä ©«
|
LD DE,(NM_NAME) ; ¤à¥á ¡ãä¥à ¯®¤ ¨¬ï ä ©«
|
||||||
@ -200,7 +201,8 @@ EX_PATH: EXX
|
|||||||
PUSH HL
|
PUSH HL
|
||||||
LD HL,TMPBUF
|
LD HL,TMPBUF
|
||||||
LD DE,(NM_DRIVE)
|
LD DE,(NM_DRIVE)
|
||||||
LD B,0
|
; A=0
|
||||||
|
LD B,A
|
||||||
LDIR
|
LDIR
|
||||||
POP HL
|
POP HL
|
||||||
EX AF,AF'
|
EX AF,AF'
|
||||||
@ -219,7 +221,8 @@ EX_PATH: EXX
|
|||||||
EX DE,HL
|
EX DE,HL
|
||||||
LD HL,TMPBUF ; 12 ¯à®¡¥«®¢
|
LD HL,TMPBUF ; 12 ¯à®¡¥«®¢
|
||||||
POP BC
|
POP BC
|
||||||
LD B,0
|
; A=0
|
||||||
|
LD B,A
|
||||||
LDIR
|
LDIR
|
||||||
POP HL
|
POP HL
|
||||||
EX AF,AF'
|
EX AF,AF'
|
||||||
|
|||||||
@ -336,7 +336,7 @@ _TST_PROC: CALL GETMEM
|
|||||||
;LD DE,CORE_BUFFERS.BUFFER+1
|
;LD DE,CORE_BUFFERS.BUFFER+1
|
||||||
LD DE,CORE_BUFFERS.BUFFER_CLP + 1
|
LD DE,CORE_BUFFERS.BUFFER_CLP + 1
|
||||||
CALL SCOPYS
|
CALL SCOPYS
|
||||||
LD A,#80 ;!HARDCODE cmd line size
|
LD A,low CLP_Buffer
|
||||||
SUB B
|
SUB B
|
||||||
LD (CORE_BUFFERS.BUFFER_CLP),A
|
LD (CORE_BUFFERS.BUFFER_CLP),A
|
||||||
;
|
;
|
||||||
@ -378,15 +378,14 @@ _TST_PROC_2:
|
|||||||
; ! „ «¥¥ á⥪ ¢ ã«¥¢®© áâà ¨æ¥! BIOS ¨ ¥ DSS-MAIN ¥ ¢ë§ë¢ âì
|
; ! „ «¥¥ á⥪ ¢ ã«¥¢®© áâà ¨æ¥! BIOS ¨ ¥ DSS-MAIN ¥ ¢ë§ë¢ âì
|
||||||
LD SP,CORE_BUFFERS.EXEBUFF + _sEXE_HEADER
|
LD SP,CORE_BUFFERS.EXEBUFF + _sEXE_HEADER
|
||||||
CALL M_PSP
|
CALL M_PSP
|
||||||
;
|
|
||||||
LD SP,(CORE_BUFFERS.EXEBUFF.SP_REG)
|
LD SP,(CORE_BUFFERS.EXEBUFF.SP_REG)
|
||||||
LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR)
|
;LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR)
|
||||||
LD DE,#0080 ;!HARDCODE CLP_Buffer
|
;LD DE,#0080 ;!HARDCODE CLP_Buffer
|
||||||
XOR A
|
;XOR A
|
||||||
SBC HL,DE
|
;SBC HL,DE
|
||||||
EX DE,HL
|
;EX DE,HL
|
||||||
LD XH,D
|
;LD XH,D
|
||||||
LD XL,E
|
;LD XL,E
|
||||||
LD DE,RETFAR ; ¤à¥á ¯/¯ "¥®¦¨¤ ®¥ § ¢¥à襨¥ ¯à®æ¥áá "
|
LD DE,RETFAR ; ¤à¥á ¯/¯ "¥®¦¨¤ ®¥ § ¢¥à襨¥ ¯à®æ¥áá "
|
||||||
PUSH DE
|
PUSH DE
|
||||||
; Current Dir 15/10/23
|
; Current Dir 15/10/23
|
||||||
@ -400,23 +399,29 @@ _TST_PROC_2:
|
|||||||
LD HL,CORE_BUFFERS.CurrentPath
|
LD HL,CORE_BUFFERS.CurrentPath
|
||||||
.set_path: CALL CHDIR_FN
|
.set_path: CALL CHDIR_FN
|
||||||
POP IX
|
POP IX
|
||||||
|
; ¯à®¢¥àª ¯¥à¥¯®«¥¨¥ ¡ãä¥à CLP
|
||||||
|
LD A,(CORE_BUFFERS.BUFFER_CLP)
|
||||||
|
LD B,DSS_Error.sys.ENV_ITEM_OVERFLOW
|
||||||
|
INC A
|
||||||
|
JP Z,LEAVE
|
||||||
;
|
;
|
||||||
EI
|
|
||||||
LD HL,(CORE_BUFFERS.EXEBUFF.PC_REG)
|
LD HL,(CORE_BUFFERS.EXEBUFF.PC_REG)
|
||||||
|
EI
|
||||||
JP (HL)
|
JP (HL)
|
||||||
;-----------------------------------------------------------------------
|
;-----------------------------------------------------------------------
|
||||||
; ! ¢ë§ë¢ ¥âáï ª®£¤ á⥪ ¢ ã«¥¢®© áâà ¨æ¥!
|
; ! ¢ë§ë¢ ¥âáï ª®£¤ á⥪ ¢ ã«¥¢®© áâà ¨æ¥!
|
||||||
M_PSP: LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR)
|
M_PSP: LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR)
|
||||||
DEC H
|
DEC H ;!FIXIT ®âáâ㯠256 (CLP buffer + data) § ¤ ®â LD_ADDR
|
||||||
LD D,H
|
LD D,H
|
||||||
LD E,L
|
LD E,L
|
||||||
INC DE
|
INC DE
|
||||||
LD BC,#00FF ;!FIXIT
|
LD BC,#00FF ;!FIXIT à §¬¥à ¯®¤ ¡ãä¥à CLP
|
||||||
LD (HL),B
|
LD (HL),B
|
||||||
LDIR
|
LDIR
|
||||||
EX DE,HL
|
EX DE,HL
|
||||||
DEC H
|
DEC H
|
||||||
LD DE,#0080 ;!FIXIT
|
;LD DE,#0080 ;!FIXIT
|
||||||
|
LD DE,#0003 ;!FIXIT
|
||||||
ADD HL,DE
|
ADD HL,DE
|
||||||
EX DE,HL
|
EX DE,HL
|
||||||
LD XH,D
|
LD XH,D
|
||||||
@ -427,67 +432,93 @@ M_PSP: LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR)
|
|||||||
INC C
|
INC C
|
||||||
LDIR
|
LDIR
|
||||||
EX DE,HL ;R06
|
EX DE,HL ;R06
|
||||||
LD (HL),B
|
;LD (HL),B
|
||||||
LD A,(TASK)
|
LD A,(TASK)
|
||||||
LD (IX-1),A
|
LD (IX-1),A
|
||||||
LD A,(EXE_MEM)
|
LD A,(EXE_MEM)
|
||||||
LD (IX-2),A
|
LD (IX-2),A
|
||||||
LD A,(EXE_FM)
|
LD A,(EXE_FM)
|
||||||
LD (IX-3),A
|
LD (IX-3),A
|
||||||
;R05
|
; â ª ¨áâ®à¨ç¥áª¨ á«®¦¨«®áì, çâ® ¤¢ 0 ¯®á«¥ ¯ à ¬¥â஢ áâப¨
|
||||||
INC HL
|
INC HL
|
||||||
LD (HL),B
|
;LD (HL),B
|
||||||
INC HL
|
INC HL
|
||||||
;!FIXIT âãâ ¢®ááâ ¢«¨¢ âì ¯à ¢¨«ìë© ª â «®£
|
;!FIXIT âãâ ¢®ááâ ¢«¨¢ âì ¯à ¢¨«ìë© ª â «®£
|
||||||
CALL CURDISK
|
CALL CURDISK
|
||||||
ADD A,'A'
|
ADD A,'A'
|
||||||
LD (HL),A
|
LD (HL),A
|
||||||
INC HL
|
INC HL
|
||||||
LD A,':'
|
LD A,':'
|
||||||
LD (HL),A
|
LD (HL),A
|
||||||
INC HL
|
INC HL
|
||||||
PUSH HL
|
PUSH HL
|
||||||
CALL CURRDIR
|
;!FIXIT âãâ ç¨â âì CURRDIR ¢ ®â¤¥«ìë© ¡ãä¥à ¨ ¨§ ¥£® ª®¯¨à®¢ âì ¢ HL ¡¥§ ¢ë室 § £à ¨æë ¡ãä¥à
|
||||||
;
|
LD HL,CORE_BUFFERS.BUFFER_CLP
|
||||||
POP HL
|
CALL CURRDIR
|
||||||
XOR A
|
|
||||||
LD BC,#0100 ;!FIXIT ¥â ¯à¨¢ï§ª¨ ª CurrentDirectory.DEPTH
|
|
||||||
CPIR ;!FIXIT ¥â ¯à®¢¥àª¨ ¢ë室 ¯® BC=0
|
|
||||||
DEC HL
|
|
||||||
DEC HL
|
|
||||||
LD A,'\' ;
|
|
||||||
CP (HL)
|
|
||||||
INC HL
|
|
||||||
JR Z,.YP_ESLA
|
|
||||||
;
|
|
||||||
LD (HL),A
|
|
||||||
INC HL
|
|
||||||
.YP_ESLA: EX DE,HL
|
|
||||||
LD HL,CORE_BUFFERS.TMPNAME
|
|
||||||
.loop: LD A,(HL)
|
|
||||||
LDI
|
|
||||||
CP ' '+1
|
|
||||||
JR NC,.loop
|
|
||||||
;
|
|
||||||
DEC DE
|
|
||||||
XOR A
|
|
||||||
LD (DE),A
|
|
||||||
LD (APPINFO.LAST_PSP_PTR),IX
|
|
||||||
;
|
;
|
||||||
|
POP DE
|
||||||
|
LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR)
|
||||||
|
SBC HL,DE
|
||||||
|
;!FIXIT ®âà ¡®â âì Z ¨ CF
|
||||||
|
LD B,H
|
||||||
|
LD C,L
|
||||||
|
;EX DE,HL
|
||||||
|
JR Z,.error_CLP
|
||||||
|
JR C,.error_CLP
|
||||||
|
; hl - ¤à¥á ¢ CLP ¤«ï § ¯¨á¨ ¯®«®£® ¨¬¥¨ ¯à¨«®¦¥¨ï á ¯ãâñ¬
|
||||||
|
; bc - ª®«¨ç¥á⢮ ®á⠢襣®áï ¬¥áâ ¢ ¡ãä¥à¥
|
||||||
|
;
|
||||||
|
LD HL,CORE_BUFFERS.BUFFER_CLP
|
||||||
|
.copy_loop: CALL .copyAndCheck
|
||||||
|
JP PO,.error_CLP
|
||||||
|
;
|
||||||
|
EX DE,HL
|
||||||
|
DEC HL
|
||||||
|
LD A,'\' ;
|
||||||
|
LD (HL),A
|
||||||
|
INC HL
|
||||||
|
.YP_ESLA: PUSH HL
|
||||||
|
PUSH BC
|
||||||
|
LD HL,CORE_BUFFERS.MASKARE
|
||||||
|
LD DE,CORE_BUFFERS.TMPNAME
|
||||||
|
CALL GetName
|
||||||
|
POP BC
|
||||||
|
POP DE
|
||||||
|
LD HL,CORE_BUFFERS.TMPNAME
|
||||||
|
;
|
||||||
|
CALL .copyAndCheck
|
||||||
|
LD (APPINFO.LAST_PSP_PTR),IX ; !FIXIT ᤥ« âì ç¥à¥§ á⥪ ¯¥à¥¬¥ëå?
|
||||||
RET
|
RET
|
||||||
;
|
;
|
||||||
SCOPYS: LD BC,#80*256 + ' '+1 ;!HARDCODE cmd line size
|
.copyAndCheck: LD A,(HL)
|
||||||
|
AND A
|
||||||
|
LDI
|
||||||
|
RET Z
|
||||||
|
JP PE,.copyAndCheck
|
||||||
|
; ¥á«¨ ¬ë âãâ, â® ¡ãä¥à ¥ å¢ â¨«® ¨ 㦮 ¢ë¤ ¢ âì ®è¨¡ªã
|
||||||
|
POP HL ; ᨬ ¥¬ ¤à¥á ¢®§¢à â
|
||||||
|
;
|
||||||
|
.error_CLP: LD A,#FF
|
||||||
|
LD (CORE_BUFFERS.BUFFER_CLP),A
|
||||||
|
RET
|
||||||
|
|
||||||
|
SCOPYS: LD BC,256*(low CLP_Buffer) + ' '+1
|
||||||
.loop: LD A,(HL)
|
.loop: LD A,(HL)
|
||||||
CP C
|
CP C
|
||||||
JR C,.copy
|
JR C,.copy
|
||||||
|
;
|
||||||
INC HL
|
INC HL
|
||||||
DJNZ .loop
|
DJNZ .loop
|
||||||
XOR A
|
XOR A
|
||||||
LD (DE),A
|
LD (DE),A
|
||||||
LD B,#80
|
LD B,low CLP_Buffer
|
||||||
RET
|
RET
|
||||||
;
|
;
|
||||||
.copy: LD BC,#80*256 + ' ' ;!HARDCODE cmd line size
|
.copy: LD BC,256*(low CLP_Buffer) + ' '
|
||||||
|
AND A
|
||||||
|
LD (DE),A
|
||||||
|
RET Z
|
||||||
|
;
|
||||||
.loop2: LD A,(HL)
|
.loop2: LD A,(HL)
|
||||||
LD (DE),A
|
LD (DE),A
|
||||||
INC HL
|
INC HL
|
||||||
@ -495,7 +526,9 @@ SCOPYS: LD BC,#80*256 + ' '+1 ;!HARDCODE cmd line size
|
|||||||
CP C
|
CP C
|
||||||
RET C
|
RET C
|
||||||
DJNZ .loop2
|
DJNZ .loop2
|
||||||
RET
|
; âã⠮訡ª - ᫨誮¬ ¤«¨ ï áâப ¯ à ¬¥â஢
|
||||||
|
INC B
|
||||||
|
RET
|
||||||
;---------------------------------------------------------------------
|
;---------------------------------------------------------------------
|
||||||
ENVPATH: DB "PATH=",0
|
ENVPATH: DB "PATH=",0
|
||||||
EXE_EXT: DB "EXE"
|
EXE_EXT: DB "EXE"
|
||||||
@ -563,9 +596,11 @@ LEAVE: ;LD A,R
|
|||||||
EX DE,HL
|
EX DE,HL
|
||||||
LD A,(ErrorLevel)
|
LD A,(ErrorLevel)
|
||||||
;R12
|
;R12
|
||||||
CP DSS_Error.sys.UNEXPECTED_APP_TRMN
|
CP DSS_Error.sys.UNEXPECTED_APP_TRMN ; #27 0010 0111 6
|
||||||
JR Z,.error_exit
|
JR Z,.error_exit
|
||||||
CP DSS_Error.sys.USER_ABORT
|
CP DSS_Error.sys.USER_ABORT ; #25 0010 0101 4
|
||||||
|
JR Z,.error_exit
|
||||||
|
CP DSS_Error.sys.ENV_ITEM_OVERFLOW ; #21 0010 0001 0
|
||||||
JR NZ,.norm_exit
|
JR NZ,.norm_exit
|
||||||
.error_exit: SCF
|
.error_exit: SCF
|
||||||
JP (HL)
|
JP (HL)
|
||||||
|
|||||||
@ -122,8 +122,4 @@ PUTCHAR: LD C,0
|
|||||||
;
|
;
|
||||||
POP HL
|
POP HL
|
||||||
RET
|
RET
|
||||||
|
|
||||||
; .NO_SCROLL:
|
|
||||||
|
|
||||||
; .CHAR: DZ "X"
|
|
||||||
;///////////////////////////////////////////////////////////////////////
|
;///////////////////////////////////////////////////////////////////////
|
||||||
312
DSS/KEYINTER.ASM
312
DSS/KEYINTER.ASM
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
; MODULE KEYINTER
|
; MODULE KEYINTER
|
||||||
;[BEGIN]
|
;[BEGIN]
|
||||||
;//MODULE: KEYINTER Keyboard Scan Codes: Set 2
|
;//MODULE: KEYINTER Keyboard Scan Codes: Set 2
|
||||||
@ -289,7 +288,7 @@ cursor_interrupt:
|
|||||||
LD A,(Cursor_Off.Flag)
|
LD A,(Cursor_Off.Flag)
|
||||||
OR A
|
OR A
|
||||||
RET Z
|
RET Z
|
||||||
.timer+1: LD A,1 ; ¯ ã§ ¬¨£ ¨ï
|
.timer+1: LD A,1 ; ¯ ã§ ¬¨£ ¨ï
|
||||||
DEC A
|
DEC A
|
||||||
CALL Z,Cursor
|
CALL Z,Cursor
|
||||||
LD (.timer),A
|
LD (.timer),A
|
||||||
@ -301,27 +300,27 @@ SETUP_CURSORS:
|
|||||||
.buffer.size EQU 2048
|
.buffer.size EQU 2048
|
||||||
;
|
;
|
||||||
in a,(SLOT3)
|
in a,(SLOT3)
|
||||||
push af ; á®åà. ¯®àâ
|
push af ; á®åà. ¯®àâ
|
||||||
ld a,((#FF00 & BANKTBL) + TXTPAGE) ; 2-© «®£. ®¬¥à áâà ¨æë à áè. „Ž‘
|
ld a,(BANKTBL+TXTPAGE) ; 2-© «®£. ®¬¥à áâà ¨æë à áè. „Ž‘
|
||||||
out (SLOT3),a
|
out (SLOT3),a
|
||||||
|
|
||||||
; ; ¯®«ãç¨âì á¨áâ. § ª®£¥.
|
; ; ¯®«ãç¨âì á¨áâ. § ª®£¥.
|
||||||
; ld de,.buffer ;!HARDCODE ¡ãä¥à ¤«ï 2048 ¡ ©â ¤ ëå
|
; ld de,.buffer ;!HARDCODE ¡ãä¥à ¤«ï 2048 ¡ ©â ¤ ëå
|
||||||
; push de
|
; push de
|
||||||
; ld c,BIOS.WIN_GET_ZG ; ¯®«ãç¨âì § ª®£¥.
|
; ld c,BIOS.WIN_GET_ZG ; ¯®«ãç¨âì § ª®£¥.
|
||||||
; rst ToBIOS
|
; rst ToBIOS
|
||||||
; ; § ¯®«¨âì ª®¤®¬ #FF 2 ¨¦¨¥ «¨¨¨
|
; ; § ¯®«¨âì ª®¤®¬ #FF 2 ¨¦¨¥ «¨¨¨
|
||||||
; ld hl,.buffer+(2048-(2*256)) ;!HARDCODE ¯®á«¥¤¨¥ 512 ¡ ©â
|
; ld hl,.buffer+(2048-(2*256)) ;!HARDCODE ¯®á«¥¤¨¥ 512 ¡ ©â
|
||||||
; ld bc,511
|
; ld bc,511
|
||||||
; ld a,CURSOR_ZG; ; ®¬¥à § ª®£¥. "ç¥àâ®çª "
|
; ld a,CURSOR_ZG; ; ®¬¥à § ª®£¥. "ç¥àâ®çª "
|
||||||
; call .fill_data_font
|
; call .fill_data_font
|
||||||
; pop hl
|
; pop hl
|
||||||
; ; § ¯®«¨âì ®áâ «ìë¥ 6 «¨¨© (¯®«ë© ¡«®ª)
|
; ; § ¯®«¨âì ®áâ «ìë¥ 6 «¨¨© (¯®«ë© ¡«®ª)
|
||||||
; ld bc,2048-513 ;!HARDCODE
|
; ld bc,2048-513 ;!HARDCODE
|
||||||
; ld a,INS_CUR_ZG ; ®¬¥à § ª®£¥. "¡«®ª"
|
; ld a,INS_CUR_ZG ; ®¬¥à § ª®£¥. "¡«®ª"
|
||||||
; call .fill_data_font
|
; call .fill_data_font
|
||||||
; pop af
|
; pop af
|
||||||
; out (SLOT3),a ; ¢®ááâ. ¯®àâ
|
; out (SLOT3),a ; ¢®ááâ. ¯®àâ
|
||||||
; ret
|
; ret
|
||||||
; ; <20> áâனª § ª®£¥. ¨ ¥£® ॣ¨áâà æ¨ï
|
; ; <20> áâனª § ª®£¥. ¨ ¥£® ॣ¨áâà æ¨ï
|
||||||
; ; ¢å®¤: a=®¬¥à § ª®£¥.
|
; ; ¢å®¤: a=®¬¥à § ª®£¥.
|
||||||
@ -333,8 +332,8 @@ SETUP_CURSORS:
|
|||||||
; ld (hl),#FF
|
; ld (hl),#FF
|
||||||
; inc de
|
; inc de
|
||||||
; ldir
|
; ldir
|
||||||
; .set: ld de,.buffer ; § ª®£¥.
|
; .set: ld de,.buffer ; § ª®£¥.
|
||||||
; ld c,BIOS.WIN_SET_ZG ; ãáâ. § ª®£¥.
|
; ld c,BIOS.WIN_SET_ZG ; ãáâ. § ª®£¥.
|
||||||
; jp ToBIOS
|
; jp ToBIOS
|
||||||
;
|
;
|
||||||
; [ ] 31/03/2025
|
; [ ] 31/03/2025
|
||||||
@ -551,9 +550,18 @@ KEYSCAN: LD IX,KEYFLAG
|
|||||||
;
|
;
|
||||||
BIT FLAG_F0,(IX+KEYFLG)
|
BIT FLAG_F0,(IX+KEYFLG)
|
||||||
JR NZ,UN_KEY
|
JR NZ,UN_KEY
|
||||||
;
|
;[ ]18/06/2026 ignore AT fake-shift (E0-12/E0-59) around extended keys
|
||||||
|
IF ENABLED_KEYBOARD_CONTROL
|
||||||
|
CALL FAKE_SHIFT
|
||||||
|
JR NC,.real_make
|
||||||
|
RES FLAG_E0,(IX+KEYFLG)
|
||||||
|
JP .RESCAN
|
||||||
|
.real_make:
|
||||||
|
ENDIF
|
||||||
LD L,A
|
LD L,A
|
||||||
CALL XLAT
|
CALL XLAT
|
||||||
|
CALL NUMPAD_KEY ; [ ]18/06/2026 keypad digit? CF=1 if emitted
|
||||||
|
JP C,.RESCAN ; emitted -> drain rest of SIO FIFO
|
||||||
CALL SHIFTS
|
CALL SHIFTS
|
||||||
RES FLAG_E0,(IX+KEYFLG)
|
RES FLAG_E0,(IX+KEYFLG)
|
||||||
IF USE_E1_SCANCODE
|
IF USE_E1_SCANCODE
|
||||||
@ -656,6 +664,13 @@ KEYSCAN: LD IX,KEYFLAG
|
|||||||
; RET
|
; RET
|
||||||
; ELSE
|
; ELSE
|
||||||
UN_KEY: RES FLAG_F0,(IX+KEYFLG)
|
UN_KEY: RES FLAG_F0,(IX+KEYFLG)
|
||||||
|
IF ENABLED_KEYBOARD_CONTROL
|
||||||
|
CALL FAKE_SHIFT
|
||||||
|
JR NC,.uk_real
|
||||||
|
RES FLAG_E0,(IX+KEYFLG)
|
||||||
|
RET
|
||||||
|
.uk_real:
|
||||||
|
ENDIF
|
||||||
LD L,A
|
LD L,A
|
||||||
CALL XLAT
|
CALL XLAT
|
||||||
CALL UNSHIFT
|
CALL UNSHIFT
|
||||||
@ -665,6 +680,76 @@ UN_KEY: RES FLAG_F0,(IX+KEYFLG)
|
|||||||
RET
|
RET
|
||||||
; ENDIF
|
; ENDIF
|
||||||
;
|
;
|
||||||
|
;--------------------------------------------------------------------------------
|
||||||
|
;[ ] 18/06/2026 NUMPAD: keypad key. DIGIT if (NumLock XOR Shift), else clean NAVIGATION.
|
||||||
|
; in : L = AT positional code (from XLAT), IX = KEYFLAG, FLAG_E0 still valid
|
||||||
|
; out: CF=1 -> keypad key fully handled and pushed via PUTSYM (caller drains FIFO)
|
||||||
|
; out: CF=0 -> not a keypad key; caller continues normal path (L preserved)
|
||||||
|
; NB: navigation is emitted as D=poscode (bit7=0), E=0 so EvComComb sees Del/arrows,
|
||||||
|
; NOT #XX|#80 which the editor reads as the Ctrl+key variant.
|
||||||
|
NUMPAD_KEY: BIT FLAG_E0,(IX+KEYFLG) ; E0 => dedicated Ins/Del/nav key -> normal path
|
||||||
|
JR NZ,.skip
|
||||||
|
LD A,L ; positional code
|
||||||
|
CP #4F ; keypad block = pos #4F..#59 (Del/. Ins/0 .. PgUp/9)
|
||||||
|
JR C,.skip ; below (keypad + - * /) -> normal path
|
||||||
|
CP #5A
|
||||||
|
JR NC,.skip ; above -> normal path
|
||||||
|
;
|
||||||
|
; mode: DIGIT if (NumLock XOR Shift), else NAVIGATION
|
||||||
|
LD A,(KEYCTRL)
|
||||||
|
AND 1<<L_SHIFT | 1<<R_SHIFT ; A<>0 if Shift held
|
||||||
|
BIT NUM_L,(IX+K_LOCK) ; Z=0 if NumLock on
|
||||||
|
JR Z,.nl_off
|
||||||
|
AND A ; NumLock ON : digit unless Shift
|
||||||
|
JR NZ,.nav ; Shift -> navigation
|
||||||
|
JR .digit
|
||||||
|
.nl_off: AND A ; NumLock OFF: navigation unless Shift
|
||||||
|
JR Z,.nav ; no Shift -> navigation
|
||||||
|
;
|
||||||
|
.digit: LD A,L
|
||||||
|
CP #4F ; keypad '.'
|
||||||
|
JR Z,.dot
|
||||||
|
SUB #50 ; #50..#59 -> 0..9
|
||||||
|
ADD A,'0' ; -> '0'..'9'
|
||||||
|
LD E,A
|
||||||
|
LD A,L
|
||||||
|
OR #80 ; D = poscode | keystroke flag
|
||||||
|
LD D,A
|
||||||
|
JR .emit
|
||||||
|
.dot: LD E,'.'
|
||||||
|
LD D,#4F | #80
|
||||||
|
JR .emit
|
||||||
|
;
|
||||||
|
.nav: LD D,L ; clean position code, bit7=0
|
||||||
|
LD E,0 ; ASCII=0 => navigation event (EvComComb)
|
||||||
|
LD A,L
|
||||||
|
CP #50 ; Ins toggles insert mode (like dedicated Ins)
|
||||||
|
CALL Z,INS_X
|
||||||
|
.emit: LD BC,(KEYFLAG) ; C=KEYFLAG B=KEYCTRL snapshot
|
||||||
|
CALL PUTSYM
|
||||||
|
SCF ; CF=1 -> handled
|
||||||
|
RET
|
||||||
|
.skip: OR A ; CF=0 -> not handled, normal path
|
||||||
|
RET
|
||||||
|
;--------------------------------------------------------------------------------
|
||||||
|
;[ ]18/06/2026 AT fake-shift detector: E0 12 / E0 59 sent around extended keys
|
||||||
|
; when NumLock/Shift is active. MUST be ignored, else it sets L_SHIFT and the
|
||||||
|
; cursor key that follows gets bit7 set in D -> editor stops recognising it.
|
||||||
|
; in : A=scancode, IX=KEYFLAG, FLAG_E0 reflects prefix ; out: CF=1 if fake-shift
|
||||||
|
IF ENABLED_KEYBOARD_CONTROL
|
||||||
|
FAKE_SHIFT: BIT FLAG_E0,(IX+KEYFLG)
|
||||||
|
JR Z,.nofake
|
||||||
|
CP #12 ; fake Left Shift
|
||||||
|
JR Z,.isfake
|
||||||
|
CP #59 ; fake Right Shift
|
||||||
|
JR Z,.isfake
|
||||||
|
.nofake: OR A ; CF=0 -> real key
|
||||||
|
RET
|
||||||
|
.isfake: SCF ; CF=1 -> ignore it
|
||||||
|
RET
|
||||||
|
ENDIF
|
||||||
|
;--------------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
|
||||||
CAPS_X: LD A,(KEYFLAG)
|
CAPS_X: LD A,(KEYFLAG)
|
||||||
XOR 1<<CAPS_L
|
XOR 1<<CAPS_L
|
||||||
@ -877,6 +962,7 @@ INPCODE: LD D,L
|
|||||||
LD E,0
|
LD E,0
|
||||||
BIT LANG_L,(IX+K_LOCK)
|
BIT LANG_L,(IX+K_LOCK)
|
||||||
JP NZ,RUSCODE
|
JP NZ,RUSCODE
|
||||||
|
;
|
||||||
LD A,(KEYCTRL)
|
LD A,(KEYCTRL)
|
||||||
AND 1<<L_SHIFT | 1<<R_SHIFT
|
AND 1<<L_SHIFT | 1<<R_SHIFT
|
||||||
JR NZ,.SHIFT
|
JR NZ,.SHIFT
|
||||||
@ -887,15 +973,17 @@ INPCODE: LD D,L
|
|||||||
RET NZ
|
RET NZ
|
||||||
LD D,L
|
LD D,L
|
||||||
BIT CAPS_L,(IX+K_LOCK)
|
BIT CAPS_L,(IX+K_LOCK)
|
||||||
LD BC,CAPSTAB
|
LD BC,ASCII_TABLES.CAPS_ENG
|
||||||
JR NZ,CONVERT.NO_SET
|
JR NZ,CONVERT.NO_SET
|
||||||
LD BC,NORMTAB
|
;
|
||||||
|
LD BC,ASCII_TABLES.ENGLISH
|
||||||
JR CONVERT.NO_SET
|
JR CONVERT.NO_SET
|
||||||
;
|
;
|
||||||
.SHIFT: LD BC,SHIFTAB
|
.SHIFT: LD BC,ASCII_TABLES.SHIFT_ENG
|
||||||
BIT CAPS_L,(IX+K_LOCK)
|
BIT CAPS_L,(IX+K_LOCK)
|
||||||
JR Z,CONVERT.SET
|
JR Z,CONVERT.SET
|
||||||
LD BC,SHF2TAB
|
;
|
||||||
|
LD BC,ASCII_TABLES.CAPS_SHIFT_ENG
|
||||||
CONVERT: ;
|
CONVERT: ;
|
||||||
.SET: SET 7,D
|
.SET: SET 7,D
|
||||||
.NO_SET: LD H,0
|
.NO_SET: LD H,0
|
||||||
@ -906,6 +994,7 @@ CONVERT: ;
|
|||||||
RUSCODE: LD A,(KEYCTRL)
|
RUSCODE: LD A,(KEYCTRL)
|
||||||
AND 1<<L_SHIFT | 1<<R_SHIFT
|
AND 1<<L_SHIFT | 1<<R_SHIFT
|
||||||
JR NZ,.SHIFT
|
JR NZ,.SHIFT
|
||||||
|
;
|
||||||
SET 7,D
|
SET 7,D
|
||||||
BIT X_ALT,(IX+K_SHIFT)
|
BIT X_ALT,(IX+K_SHIFT)
|
||||||
RET NZ
|
RET NZ
|
||||||
@ -913,15 +1002,17 @@ RUSCODE: LD A,(KEYCTRL)
|
|||||||
RET NZ
|
RET NZ
|
||||||
LD D,L
|
LD D,L
|
||||||
BIT CAPS_L,(IX+K_LOCK)
|
BIT CAPS_L,(IX+K_LOCK)
|
||||||
LD BC,CAPSRUS
|
LD BC,ASCII_TABLES.CAPS_RUS
|
||||||
JR NZ,CONVERT.NO_SET
|
JR NZ,CONVERT.NO_SET
|
||||||
LD BC,NORMRUS
|
;
|
||||||
|
LD BC,ASCII_TABLES.RUSSIAN
|
||||||
JR CONVERT.NO_SET
|
JR CONVERT.NO_SET
|
||||||
;
|
;
|
||||||
.SHIFT: LD BC,SHIFRUS
|
.SHIFT: LD BC,ASCII_TABLES.SHIFT_RUS
|
||||||
BIT CAPS_L,(IX+K_LOCK)
|
BIT CAPS_L,(IX+K_LOCK)
|
||||||
JR Z,CONVERT.SET
|
JR Z,CONVERT.SET
|
||||||
LD BC,SHF2RUS
|
;
|
||||||
|
LD BC,ASCII_TABLES.CAPS_SHIFT_RUS
|
||||||
JR CONVERT.SET
|
JR CONVERT.SET
|
||||||
|
|
||||||
;-----------------------------------------------------------------------
|
;-----------------------------------------------------------------------
|
||||||
@ -929,32 +1020,32 @@ RUSCODE: LD A,(KEYCTRL)
|
|||||||
K_SETUP: INC B
|
K_SETUP: INC B
|
||||||
DJNZ K_SND_R
|
DJNZ K_SND_R
|
||||||
; subfunc 0
|
; subfunc 0
|
||||||
KEYMAP: LD BC,ENDNORM-NORMTAB
|
KEYMAP: LD BC,ASCII_TABLES.Size
|
||||||
BIT 7,A
|
BIT 7,A
|
||||||
JR NZ,READMAP
|
JR NZ,READMAP
|
||||||
;
|
;
|
||||||
LD DE,NORMTAB
|
LD DE,ASCII_TABLES.ENGLISH
|
||||||
OR A
|
OR A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,SHIFTAB
|
LD DE,ASCII_TABLES.SHIFT_ENG
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,CAPSTAB
|
LD DE,ASCII_TABLES.CAPS_ENG
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,SHF2TAB
|
LD DE,ASCII_TABLES.CAPS_SHIFT_ENG
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,NORMRUS
|
LD DE,ASCII_TABLES.RUSSIAN
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,SHIFRUS
|
LD DE,ASCII_TABLES.SHIFT_RUS
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,CAPSRUS
|
LD DE,ASCII_TABLES.CAPS_RUS
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
LD DE,SHF2RUS
|
LD DE,ASCII_TABLES.CAPS_SHIFT_RUS
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.LTAB
|
JR Z,.LTAB
|
||||||
;
|
;
|
||||||
@ -967,28 +1058,28 @@ KEYMAP: LD BC,ENDNORM-NORMTAB
|
|||||||
RET
|
RET
|
||||||
;
|
;
|
||||||
READMAP: RES 7,A
|
READMAP: RES 7,A
|
||||||
LD DE,NORMTAB
|
LD DE,ASCII_TABLES.ENGLISH
|
||||||
OR A
|
OR A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,SHIFTAB
|
LD DE,ASCII_TABLES.SHIFT_ENG
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,CAPSTAB
|
LD DE,ASCII_TABLES.CAPS_ENG
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,SHF2TAB
|
LD DE,ASCII_TABLES.CAPS_SHIFT_ENG
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,NORMRUS
|
LD DE,ASCII_TABLES.RUSSIAN
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,SHIFRUS
|
LD DE,ASCII_TABLES.SHIFT_RUS
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,CAPSRUS
|
LD DE,ASCII_TABLES.CAPS_RUS
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
LD DE,SHF2RUS
|
LD DE,ASCII_TABLES.CAPS_SHIFT_RUS
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.RTAB
|
JR Z,.RTAB
|
||||||
XOR A ; ????? ¬®¦¥â âãâ ¤® .INVALID_COMMAND?
|
XOR A ; ????? ¬®¦¥â âãâ ¤® .INVALID_COMMAND?
|
||||||
@ -1273,86 +1364,95 @@ Esc EQU #1B
|
|||||||
Bcs EQU #08
|
Bcs EQU #08
|
||||||
Tab EQU #09
|
Tab EQU #09
|
||||||
Cps EQU #00
|
Cps EQU #00
|
||||||
Spc EQU #20
|
;Spc EQU #20
|
||||||
Ent EQU #0D
|
Ent EQU #0D
|
||||||
|
|
||||||
;Standart ASCII tables
|
;Standart ASCII tables
|
||||||
NORMTAB DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
MODULE ASCII_TABLES
|
||||||
DB Tab,"q","w","e","r","t","y","u","i","o","p","[","]"
|
Size EQU 90 ; <20> §¬¥à «î¡®© â ¡«¨æë
|
||||||
DB Cps,"a","s","d","f","g","h","j","k","l",";","'",Ent
|
ENGLISH: DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
||||||
DB #00,"z","x","c","v","b","n","m",#2C,".","/",#00,#5C
|
DB Tab,"q","w","e","r","t","y","u","i","o","p","[","]"
|
||||||
DB #00,#00,Spc,#00,#00
|
DB Cps,"a","s","d","f","g","h","j","k","l",";","'",Ent
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,"z","x","c","v","b","n","m",",",".","/",#00,'\' ;
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
ENDNORM
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-ENGLISH : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
SHIFTAB DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs
|
SHIFT_ENG: DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs
|
||||||
DB Tab,"Q","W","E","R","T","Y","U","I","O","P","{","}"
|
DB Tab,"Q","W","E","R","T","Y","U","I","O","P","{","}"
|
||||||
DB Cps,"A","S","D","F","G","H","J","K","L",":",#22,Ent
|
DB Cps,"A","S","D","F","G","H","J","K","L",":",#22,Ent
|
||||||
DB #00,"Z","X","C","V","B","N","M","<",">","?",#00,"|"
|
DB #00,"Z","X","C","V","B","N","M","<",">","?",#00,"|"
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-SHIFT_ENG : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
CAPSTAB DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
CAPS_ENG: DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
||||||
DB Tab,"Q","W","E","R","T","Y","U","I","O","P","[","]"
|
DB Tab,"Q","W","E","R","T","Y","U","I","O","P","[","]"
|
||||||
DB Cps,"A","S","D","F","G","H","J","K","L",";","'",Ent
|
DB Cps,"A","S","D","F","G","H","J","K","L",";","'",Ent
|
||||||
DB #00,"Z","X","C","V","B","N","M",#2C,".","/",#00,#5C
|
DB #00,"Z","X","C","V","B","N","M",",",".","/",#00,'\' ;
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-CAPS_ENG : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
SHF2TAB DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs
|
CAPS_SHIFT_ENG: DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs
|
||||||
DB Tab,"q","w","e","r","t","y","u","i","o","p","{","}"
|
DB Tab,"q","w","e","r","t","y","u","i","o","p","{","}"
|
||||||
DB Cps,"a","s","d","f","g","h","j","k","l",":",#22,Ent
|
DB Cps,"a","s","d","f","g","h","j","k","l",":",#22,Ent
|
||||||
DB #00,"z","x","c","v","b","n","m","<",">","?",#00,"|"
|
DB #00,"z","x","c","v","b","n","m","<",">","?",#00,"|"
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-CAPS_SHIFT_ENG : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
;Standart Russian tables
|
;Standart Russian tables
|
||||||
NORMRUS DB #F1,Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
RUSSIAN: DB #F1,Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
||||||
DB Tab,#A9,#E6,#E3,#AA,#A5,#AD,#A3,#E8,#E9,#A7,#E5,#EA
|
DB Tab,#A9,#E6,#E3,#AA,#A5,#AD,#A3,#E8,#E9,#A7,#E5,#EA
|
||||||
DB Cps,#E4,#EB,#A2,#A0,#AF,#E0,#AE,#AB,#A4,#A6,#ED,Ent
|
DB Cps,#E4,#EB,#A2,#A0,#AF,#E0,#AE,#AB,#A4,#A6,#ED,Ent
|
||||||
DB #00,#EF,#E7,#E1,#AC,#A8,#E2,#EC,#A1,#EE,".",#00,#5C
|
DB #00,#EF,#E7,#E1,#AC,#A8,#E2,#EC,#A1,#EE,".",#00,'\' ;
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-RUSSIAN : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
SHIFRUS DB #F0,Esc,"!",#22,"#","$",":",#2C,".",";","?","%","_","+",Bcs
|
SHIFT_RUS: DB #F0,Esc,"!",'"',"#",";","%",":","?","*","(",")","_","+",Bcs
|
||||||
DB Tab,#89,#96,#93,#8A,#85,#8D,#83,#98,#99,#87,#95,#9A
|
DB Tab,#89,#96,#93,#8A,#85,#8D,#83,#98,#99,#87,#95,#9A
|
||||||
DB Cps,#94,#9B,#82,#80,#8F,#90,#8E,#8B,#84,#86,#9D,Ent
|
DB Cps,#94,#9B,#82,#80,#8F,#90,#8E,#8B,#84,#86,#9D,Ent
|
||||||
DB #00,#9F,#97,#91,#8C,#88,#92,#9C,#81,#9E,#2C,#00,"|"
|
DB #00,#9F,#97,#91,#8C,#88,#92,#9C,#81,#9E,",",#00,"/"
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-SHIFT_RUS : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
CAPSRUS DB #F0,Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
CAPS_RUS: DB #F0,Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
||||||
DB Tab,#89,#96,#93,#8A,#85,#8D,#83,#98,#99,#87,#95,#9A
|
DB Tab,#89,#96,#93,#8A,#85,#8D,#83,#98,#99,#87,#95,#9A
|
||||||
DB Cps,#94,#9B,#82,#80,#8F,#90,#8E,#8B,#84,#86,#9D,Ent
|
DB Cps,#94,#9B,#82,#80,#8F,#90,#8E,#8B,#84,#86,#9D,Ent
|
||||||
DB #00,#9F,#97,#91,#8C,#88,#92,#9C,#81,#9E,".",#00,#5C
|
DB #00,#9F,#97,#91,#8C,#88,#92,#9C,#81,#9E,".",#00,'\' ;
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-CAPS_RUS : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
SHF2RUS DB #F1,Esc,"!",#22,"#","$",":",#2C,".",";","?","%","_","+",Bcs
|
CAPS_SHIFT_RUS: DB #F1,Esc,"!",'"',"#",";","%",":","?","*","(",")","_","+",Bcs
|
||||||
DB Tab,#A9,#E6,#E3,#AA,#A5,#AD,#A3,#E8,#E9,#A7,#E5,#EA
|
DB Tab,#A9,#E6,#E3,#AA,#A5,#AD,#A3,#E8,#E9,#A7,#E5,#EA
|
||||||
DB Cps,#E4,#EB,#A2,#A0,#AF,#E0,#AE,#AB,#A4,#A6,#ED,Ent
|
DB Cps,#E4,#EB,#A2,#A0,#AF,#E0,#AE,#AB,#A4,#A6,#ED,Ent
|
||||||
DB #00,#EF,#E7,#E1,#AC,#A8,#E2,#EC,#A1,#EE,#2C,#00,"|"
|
DB #00,#EF,#E7,#E1,#AC,#A8,#E2,#EC,#A1,#EE,",",#00,"/"
|
||||||
DB #00,#00,Spc,#00,#00
|
DB #00,#00," ",#00,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||||||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||||||
|
.Size EQU $-CAPS_SHIFT_RUS : ASSERT .Size = Size, '-> Error! This table has wrong size!!!'
|
||||||
|
|
||||||
|
ENDMODULE ; ASCII_TABLES
|
||||||
;================================
|
;================================
|
||||||
|
|
||||||
;//MODULE: KEYINTER
|
;//MODULE: KEYINTER
|
||||||
;[END]
|
;[END]
|
||||||
; ENDMODULE
|
; ENDMODULE
|
||||||
101
DSS/KNOWN.BUG
101
DSS/KNOWN.BUG
@ -7,7 +7,106 @@ FIXED:
|
|||||||
|
|
||||||
+ ®è¨¡ª ¯à¨ ¯à®á¬®âॠª â «®£ ¢ äãªæ¨ïå ãáâ ®¢ª¨ âਡã⮢ ¯à®¯ã᪠îâáï á¨áâ¥¬ë¥ ä ©«ë. ¯/¯ SEARCH MASK=#23
|
+ ®è¨¡ª ¯à¨ ¯à®á¬®âॠª â «®£ ¢ äãªæ¨ïå ãáâ ®¢ª¨ âਡã⮢ ¯à®¯ã᪠îâáï á¨áâ¥¬ë¥ ä ©«ë. ¯/¯ SEARCH MASK=#23
|
||||||
|
|
||||||
- ¨£®à¨à®¢ ¨¥ ®è¨¡®ª ¯à¨ § ¯¨á¨ á¨á⥬ëå ®¡« á⥩ FAT/DIR, ¥¢®§¬®¦®áâì ®âà ¡®â âì ®è¨¡ªã write-protect, â ª ª ª ® â¥àï¥âáï ¯à¨ ¯®¯ë⪥ § ¯¨á âì ¨§¬¥¥ë© ª â «®£ ¤¨áª. <20>® ¢®§¨ª ¥â ®è¨¡ª file not found â ª ª ª áà §ã ¯®á«¥ á®§¤ ¨ï á¨á⥬ ®âªàë¢ ¥â ä ©«.
|
- ¨£®à¨à®¢ ¨¥ ®è¨¡®ª ¯à¨ § ¯¨á¨ á¨á⥬ëå ®¡« á⥩ FAT/DIR, ¥¢®§¬®¦®áâì ®âà ¡®â âì ®è¨¡ªã write-protect,
|
||||||
|
â ª ª ª ® â¥àï¥âáï ¯à¨ ¯®¯ë⪥ § ¯¨á âì ¨§¬¥¥ë© ª â «®£ ¤¨áª. <20>® ¢®§¨ª ¥â ®è¨¡ª file not found
|
||||||
|
â ª ª ª áà §ã ¯®á«¥ á®§¤ ¨ï á¨á⥬ ®âªàë¢ ¥â ä ©«.
|
||||||
|
|
||||||
- ®è¨¡ª à §¡®à ¤®¯ãá⨬®£® ¨¬¥¨ ä ©« , ¥á«¨ ®® á®á⮨⠨§ "." â ª ª ª ¯®¤à §ã¬¥¢ ¥âáï ¯à®¡¥«ë â®çª ¯à®¡¥«ë.
|
- ®è¨¡ª à §¡®à ¤®¯ãá⨬®£® ¨¬¥¨ ä ©« , ¥á«¨ ®® á®á⮨⠨§ "." â ª ª ª ¯®¤à §ã¬¥¢ ¥âáï ¯à®¡¥«ë â®çª ¯à®¡¥«ë.
|
||||||
|
|
||||||
|
======================================================= AI =======================================================
|
||||||
|
1.1. CREATE (Create.asm) ? Žá¨à®â¥¢è ï § ¯¨áì ª â «®£ ¯à¨ á¡®¥ ®âªàëâ¨ï
|
||||||
|
- <20>®á«¥ á®§¤ ¨ï § ¯¨á¨ ª â «®£ (WRT_HND, SAVEDIR) ¢ë§ë¢ ¥âáï
|
||||||
|
OPEN_FN.FILE. …᫨ ®âªàë⨥ ä ©« ¥ 㤠ñâáï ( ¯à¨¬¥à, ¥â
|
||||||
|
᢮¡®¤ëå ¬ ¨¯ã«ïâ®à®¢, ®è¨¡ª ¤¨áª ), ¢ ª â «®£¥ ®áâ ñâáï
|
||||||
|
ä ©«®¢ ï § ¯¨áì á ã«¥¢ë¬ à §¬¥à®¬ ¨ ¡¥§ ¤ ëå. <20>®á«¥¤ãî騥
|
||||||
|
¯®¯ë⪨ á®§¤ âì ä ©« á ⥬ ¦¥ ¨¬¥¥¬ ¯à¨¢¥¤ãâ ª ®è¨¡ª¥
|
||||||
|
FILE_EXISTS, å®âï ä ©« ä ªâ¨ç¥áª¨ ¯ãáâ ¨ ¥ ®âªàëâ.
|
||||||
|
- ˆá¯à ¢«¥¨¥: ¥á«¨ OPEN_FN.FILE ¢®§¢à é ¥â ®è¨¡ªã, 㦮 㤠«¨âì
|
||||||
|
⮫쪮 çâ® á®§¤ ãî § ¯¨áì ¢ë§®¢®¬ DELETE_REC_FAT.
|
||||||
|
|
||||||
|
1.2. ATTRIB (Attribute.asm) ? <20>¥ª®à४âë© à¥¦¨¬ ®âªàëâ¨ï ¤«ï § ¯¨á¨ âਡã⮢
|
||||||
|
- <20>ਠãáâ ®¢ª¥ âਡãâ (B=1) ¢ë§ë¢ ¥âáï .OPENATR, ª®â®à ï
|
||||||
|
®âªàë¢ ¥â ä ©« á ०¨¬®¬ ¯® 㬮«ç ¨î (A=0 ? ç⥨¥/§ ¯¨áì).
|
||||||
|
…᫨ ä ©« 㦥 ®âªàëâ ¤à㣨¬ ¯à®æ¥áᮬ § ¯¨áì, ®¯¥à æ¨ï ¬®¦¥â
|
||||||
|
§ ¢¥àè¨âìáï ®è¨¡ª®© ¨«¨ àãè¨âì ¡«®ª¨à®¢ª¨. <20>¥ ¯à®¢¥àï¥âáï
|
||||||
|
⥪ã騩 ०¨¬ ¤®áâ㯠.
|
||||||
|
- ˆá¯à ¢«¥¨¥: ®âªàë¢ âì ä ©« á ०¨¬®¬ 0 (ç⥨¥/§ ¯¨áì) ⮫쪮
|
||||||
|
¥á«¨ ® ¥ ¡ë« ®âªàëâ à ¥¥; ¯à¨ ¥®¡å®¤¨¬®á⨠¨á¯®«ì§®¢ âì
|
||||||
|
®â¤¥«ìë© § ¯à®á ¡«®ª¨à®¢ª¨.
|
||||||
|
|
||||||
|
1.3. LEAV (Execute.ASM) ? Žâáãâá⢨¥ ¯à®¢¥àª¨ SP ¢ EXE-§ £®«®¢ª¥
|
||||||
|
- <20>ਠ§ ¯ã᪥ EXE-ä ©« § 票¥ SP_REG ¨§ § £®«®¢ª § £à㦠¥âáï
|
||||||
|
¢ SP ¡¥§ ¯à®¢¥à®ª. <20>¥ª®à४⮥ § 票¥ ( ¯à¨¬¥à, 0x0000)
|
||||||
|
¯à¨¢¥¤ñâ ª ¥¬¥¤«¥®¬ã ªà åã á⥪ . †¥« â¥«ì® ¯à®¢¥àïâì,
|
||||||
|
¯®¯ ¤ ¥â «¨ SP ¢ ¤®¯ãáâ¨¬ë© ¤¨ ¯ §® ¯ ¬ï⨠§ ¤ ç¨, ¨
|
||||||
|
ãáâ ¢«¨¢ âì ¡¥§®¯ ᮥ § 票¥ ¯à¨ ®è¨¡ª¥.
|
||||||
|
|
||||||
|
1.4. Read (Read.asm) ? <20>¥á¡ « á¨à®¢ ë© á⥪ ¯ã⨠®è¨¡ª¨
|
||||||
|
“⢥ত¥¨¥ ¨§ ¯¥à¢® ç «ì®£® «¨§ ®ª § «®áì ¥¢¥àë¬ ? ¯®á«¥
|
||||||
|
âàñå PUSH (BC,HL,DE) ¢ë¯®«ïîâáï âਠPOP (HL,HL,BC), á⥪
|
||||||
|
¡ « á¨àã¥âáï. ޤ ª® DE ®áâ ñâáï ¨á¯®àç¥ë¬, çâ® ¤®¯ãá⨬® ¯®
|
||||||
|
ᮣ« 襨î. <20>஡«¥¬ë á® á⥪®¬ ¥â.
|
||||||
|
|
||||||
|
’¥¬ ¥ ¬¥¥¥, ¢ í⮬ ¦¥ ¬®¤ã«¥ ¥áâì ¤à㣮© ¯®â¥æ¨ «ìë© ¤¥ä¥ªâ:
|
||||||
|
¢ .ROV1 ¯à¨ ãᯥ讬 ç⥨¨ ¨á¯®«ì§ã¥âáï EXX ¨ ¬®¤¨ä¨ª æ¨ï á⥪
|
||||||
|
¢ «ìâ¥à ⨢ëå ॣ¨áâà å, çâ® ¬®¦¥â ¯à¨¢¥á⨠ª ¯ãâ ¨æ¥, ¥á«¨
|
||||||
|
£¤¥-â® ¥ á®åà ¥ë ¢â®à¨çë¥ à¥£¨áâàë. <20>¥ª®¬¥¤ã¥âáï âé ⥫ì®
|
||||||
|
¯à®¢¥àïâì ¨á¯®«ì§®¢ ¨¥ EXX ¢ ®¡à ¡®â稪 å ®è¨¡®ª.
|
||||||
|
|
||||||
|
1.5. ENV_EX (Environ.asm) ? ˆ£®à¨à®¢ ¨¥ ®è¨¡ª¨ ¯¥à¥¯®«¥¨ï ¡ãä¥à
|
||||||
|
- ”ãªæ¨ï ENV_EX ¬®¦¥â ãáâ ®¢¨âì CF=1, ¥á«¨ ¢å®¤ ï áâப
|
||||||
|
®ªà㦥¨ï ᫨誮¬ ¤«¨ ï, ® ¢ë§ë¢ î騥 ¥ñ ¯à®æ¥¤ãàë GETENV
|
||||||
|
¨ SETENV ¨ª ª ¥ «¨§¨àãîâ íâ®â ä« £. <20>¥à¥¬¥ ï á®§¤ ñâáï
|
||||||
|
¨«¨ ç¨â ¥âáï á ®¡à¥§ ë¬ § 票¥¬ ¡¥§ ¯à¥¤ã¯à¥¦¤¥¨ï, çâ®
|
||||||
|
¬®¦¥â ¯à¨¢¥á⨠ª âà㤮㫮¢¨¬ë¬ ®è¨¡ª ¬ ª®ä¨£ãà æ¨¨.
|
||||||
|
- ˆá¯à ¢«¥¨¥: ¤®¡ ¢¨âì ¯à®¢¥àªã CF ¯®á«¥ ¢ë§®¢ ENV_EX ¨
|
||||||
|
¢®§¢à é âì ®è¨¡ªã ENV_ITEM_OVERFLOW.
|
||||||
|
|
||||||
|
1.6. diskINF GetFreeSpace (diskINF.asm) ? ‚®§¬®¦®¥ § ¢¨á ¨¥ ¯à¨
|
||||||
|
¯®¢à¥¦¤ñ®© FAT
|
||||||
|
- –¨ª« ¯®¤áçñâ ᢮¡®¤ëå ª« áâ¥à®¢ ¯à®¢¥àï¥â READ_FROM_FAT,
|
||||||
|
® ¥ ®£à ¨ç¨¢ ¥â ç¨á«® ¨â¥à 権. …᫨ 楯®çª ª« áâ¥à®¢
|
||||||
|
§ ¬ªãâ ¨«¨ â ¡«¨æ FAT ¨á¯®àç¥ , 横« ¬®¦¥â áâ âì ¡¥áª®¥çë¬.
|
||||||
|
- ˆá¯à ¢«¥¨¥: ¤®¡ ¢¨âì áçñâ稪 ¨â¥à 権, à ¢ë© ®¡é¥¬ã ç¨á«ã
|
||||||
|
ª« áâ¥à®¢, ¨«¨ ¨á¯®«ì§®¢ âì ¯¯ à âë© â ©¬- ãâ.
|
||||||
|
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
2. <20><>…„‹Ž†…<E280A0>ˆŸ <20>Ž Ž<>’ˆŒˆ‡€–ˆˆ
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
2.2. Šíè¨à®¢ ¨¥ ª â «®£
|
||||||
|
- Œ®£¨¥ äãªæ¨¨ (OPEN, DELETE, RENAME) ¬®£®ªà â® § £à㦠îâ
|
||||||
|
®¤¨ ¨ â®â ¦¥ ª â «®£ ç¥à¥§ LOADDIR. Œ®¦® ¯à®¢¥àïâì, ¥
|
||||||
|
ᮢ¯ ¤ ¥â «¨ ⥪ã騩 ®âªàëâë© ª â «®£ á FM_BUF[0], ¨ ¨§¡¥£ âì
|
||||||
|
¯®¢â®à®£® ç⥨ï.
|
||||||
|
|
||||||
|
|
||||||
|
2.5. Ž¯â¨¬¨§ æ¨ï WRITE_FAT_TABLE
|
||||||
|
- <20>ਠ§ ¯¨á¨ ªíè FAT ¤¨áª ¯à®¢¥àï¥âáï § 票¥ CacheUpdated,
|
||||||
|
¨ § ¯¨áë¢ îâáï ⮫쪮 ¨§¬¥ñë¥ ¡«®ª¨. ޤ ª® ¯à¨
|
||||||
|
¯®á«¥¤®¢ ⥫쮩 § ¯¨á¨ ¬®£¨å ª« áâ¥à®¢ ç áâ® ¢ë§ë¢ ¥âáï
|
||||||
|
WRITE_FAT_TABLE. Œ®¦® ®â«®¦¨âì § ¯¨áì ¤® § ªàëâ¨ï ä ©« ¨«¨
|
||||||
|
ª®¯¨âì ¨§¬¥¥¨ï.
|
||||||
|
|
||||||
|
2.6. ˆ§¡¥£ ¨¥ ¯®¢â®à®£® ç⥨ï BPB
|
||||||
|
- ‚ OPENDSK ª ¦¤ë© à § ¢ë§ë¢ ¥âáï RD_BPB, ¤ ¦¥ ¥á«¨ ¤¨áª 㦥
|
||||||
|
®âªàëâ á ⥬¨ ¦¥ ¯ à ¬¥âà ¬¨. Œ®¦® ¤®¡ ¢¨âì ¯®«¥ ¢ FS_Buffer,
|
||||||
|
ᨣ «¨§¨àãî饥, çâ® BPB ª®à४â¥, ¨ ¯à®¯ã᪠âì ¯®¢â®à®¥
|
||||||
|
ç⥨¥ ¯à¨ ®âáãâá⢨¨ á¬¥ë ¤¨áª .
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
3. Ž<>™ˆ… ‡€Œ…—€<E28094>ˆŸ
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
3.3. Žâáãâá⢨¥ ¯à®¢¥à®ª £à ¨æ ¡ãä¥à®¢
|
||||||
|
- ‚ à拉 ¯à®æ¥¤ãà ( ¯à¨¬¥à, EXEC Build PSP, Environ) ¨á¯®«ì§ãîâáï
|
||||||
|
䨪á¨à®¢ ë¥ ª®áâ âë à §¬¥à ¡ãä¥à (#100, #80). †¥« ⥫ì®
|
||||||
|
¯à®¢¥àïâì, çâ® ¤ ë¥ ¥ ¢ë室ïâ § £à ¨æë ¢ë¤¥«¥®© ¯ ¬ïâ¨.
|
||||||
|
|
||||||
|
3.4. “áâ ॢ訩 ª®¤
|
||||||
|
- ‚ ä ©« å ¯à¨áãâáâ¢ãîâ § ª®¬¬¥â¨à®¢ ë¥ áâ àë¥ à¥ «¨§ 樨
|
||||||
|
( ¯à¨¬¥à, áâ àë© ECHOKEY á ªãàá®à®¬, áâ àë© PUTCHAR). ˆå
|
||||||
|
㤠«¥¨¥ 㬥ìè¨â ®¡êñ¬ ¨á室®£® ⥪áâ ¨ ã«ãçè¨â ç¨â ¥¬®áâì.
|
||||||
|
|
||||||
|
================================================================
|
||||||
@ -44,7 +44,8 @@ MOUSE_BAUD:
|
|||||||
DEFINE CHANGE_LANG_CTRL_SHIFT 1 ; [x] 0: Ctrl + Space, 1: Ctrl + Shift.
|
DEFINE CHANGE_LANG_CTRL_SHIFT 1 ; [x] 0: Ctrl + Space, 1: Ctrl + Shift.
|
||||||
DEFINE BREAK_PROCESS_CODE #AC00 ; CTRL+C
|
DEFINE BREAK_PROCESS_CODE #AC00 ; CTRL+C
|
||||||
DEFINE USE_E1_SCANCODE 0
|
DEFINE USE_E1_SCANCODE 0
|
||||||
;DEFINE CLASSIC_CURSOR 0
|
DEFINE ENABLED_KEYBOARD_CONTROL 0 ; 1=host can talk to kbd (0xED LEDs) => handle AT fake-shift (E0 12/59).
|
||||||
|
; ; HW is receive-only -> keep 0
|
||||||
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
|
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
76
DSS/drivers/DRV_TO_SYS_ERRORS.ASM
Normal file
76
DSS/drivers/DRV_TO_SYS_ERRORS.ASM
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
; 19/04/2025 ¢â®¯¥à¥¢®¤ ®¬¥à ®è¨¡ª¨ DRV/BIOS ¢ SYS
|
||||||
|
DRV_ERROR_TO_SYS:
|
||||||
|
RET NC
|
||||||
|
RLA
|
||||||
|
JR NC,.no_correction
|
||||||
|
;
|
||||||
|
PUSH HL
|
||||||
|
PUSH AF
|
||||||
|
;
|
||||||
|
SRL A
|
||||||
|
CP .Size
|
||||||
|
LD HL,.TABLE
|
||||||
|
ADD A,L
|
||||||
|
JR NC,.no_inc
|
||||||
|
;
|
||||||
|
INC H
|
||||||
|
.no_inc: LD L,A
|
||||||
|
LD L,(HL)
|
||||||
|
POP AF
|
||||||
|
LD A,L
|
||||||
|
POP HL
|
||||||
|
RET
|
||||||
|
;
|
||||||
|
.no_correction: RRA
|
||||||
|
RET
|
||||||
|
|
||||||
|
.TABLE: DB DSS_Error.sys.Unknown_Error ;BIOS.Error.NoErrors ; 0
|
||||||
|
DB DSS_Error.sys.INVALID_FUNCTION ;BIOS.Error.InvalidSubFunction ; 1
|
||||||
|
DB DSS_Error.sys.INVALID_DRIVE ;BIOS.Error.BadNumber ; 2
|
||||||
|
DB DSS_Error.sys.UNKNOWN_FORMAT ;BIOS.Error.UnknownDevice ; 3
|
||||||
|
DB DSS_Error.sys.NOT_READY ;BIOS.Error.NotReady ; 4
|
||||||
|
DB DSS_Error.sys.SEEK_ERROR ;BIOS.Error.Seek ; 5
|
||||||
|
DB DSS_Error.sys.SECTOR_NOT_FOUND ;BIOS.Error.SectorNotFound ; 6
|
||||||
|
DB DSS_Error.sys.CRC_ERROR ;BIOS.Error.CRC ; 7
|
||||||
|
DB DSS_Error.sys.WRITE_PROTECT ;BIOS.Error.WriteProtect ; 8
|
||||||
|
DB DSS_Error.sys.READ_ERROR ;BIOS.Error.Read ; 9
|
||||||
|
DB DSS_Error.sys.WRITE_ERROR ;BIOS.Error.Write ; 10
|
||||||
|
DB DSS_Error.sys.DRIVE_FAILURE ;BIOS.Error.Failure ; 11
|
||||||
|
DB DSS_Error.sys.BUSY_NO_MEDIA ;BIOS.Error.Busy ; 12
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#8D ; 13
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#8E ; 14
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#8F ; 15
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#90 ; 16
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#91 ; 17
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#92 ; 18
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#93 ; 19
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#94 ; 20
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#95 ; 21
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#96 ; 22
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#97 ; 23
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#98 ; 24
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#99 ; 25
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#9A ; 26
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#9B ; 27
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#9C ; 28
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#9D ; 29
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;#9E ; 30
|
||||||
|
DB DSS_Error.sys.NOT_SUPPORTED ;BIOS.Error.NotSupported ; 31
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI.NoSence ; 32
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI.RecoveredError; 33
|
||||||
|
DB DSS_Error.sys.NOT_READY ;BIOS.Error.ATAPI.NotReady ; 34
|
||||||
|
DB DSS_Error.sys.BUSY_NO_MEDIA ;BIOS.Error.ATAPI.MediumError ; 35
|
||||||
|
DB DSS_Error.sys.DRIVE_FAILURE ;BIOS.Error.ATAPI.HardwareError ; 36
|
||||||
|
DB DSS_Error.sys.INVALID_ACCESS ;BIOS.Error.ATAPI.IllegalRequest; 37
|
||||||
|
DB DSS_Error.sys.MEDIA_CHANGED ;BIOS.Error.ATAPI.UnitAttention ; 38
|
||||||
|
DB DSS_Error.sys.ACCESS_DENIED ;BIOS.Error.ATAPI.DataProtect ; 39
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI; ; 40
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI; ; 41
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI; ; 42
|
||||||
|
DB DSS_Error.sys.NOT_READY ;BIOS.Error.ATAPI.AbortedCommand; 43
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI; ; 44
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI; ; 45
|
||||||
|
DB DSS_Error.sys.WRITE_ERROR ;BIOS.Error.ATAPI.Miscompare ; 46
|
||||||
|
DB DSS_Error.sys.Unknown_Error ;BIOS.Error.ATAPI; ; 47
|
||||||
|
DB DSS_Error.sys.NOT_READY ;BIOS.Error.ATAPI.TimeOut ; 48
|
||||||
|
.Size EQU .TABLE - $
|
||||||
@ -42,7 +42,7 @@ MAKE_BATCH_PRM_ARRAY:
|
|||||||
ret z
|
ret z
|
||||||
cp " "
|
cp " "
|
||||||
jr z,.loop
|
jr z,.loop
|
||||||
cp 9 ; Tab
|
cp "\t" ; Tab
|
||||||
jr z,.loop
|
jr z,.loop
|
||||||
ex de,hl
|
ex de,hl
|
||||||
ld (hl),e
|
ld (hl),e
|
||||||
@ -231,9 +231,11 @@ MOVWORD:
|
|||||||
ld b,a
|
ld b,a
|
||||||
.loop: ld a,(hl)
|
.loop: ld a,(hl)
|
||||||
ld (de),a
|
ld (de),a
|
||||||
|
cp "\t" ; TAB - in-line blank, keep it (MS-DOS bat)
|
||||||
|
jr z,.cont
|
||||||
cp " "
|
cp " "
|
||||||
jr c,.loop_
|
jr c,.loop_ ; <0x20 (CR/LF) -> end of line
|
||||||
inc hl
|
.cont: inc hl
|
||||||
inc de
|
inc de
|
||||||
djnz .loop
|
djnz .loop
|
||||||
scf
|
scf
|
||||||
@ -281,6 +283,8 @@ CMDMODE:
|
|||||||
;ld (D96A6),a ; (inline.asm)
|
;ld (D96A6),a ; (inline.asm)
|
||||||
call EVALCMD ; (batch.asm)
|
call EVALCMD ; (batch.asm)
|
||||||
RET C
|
RET C
|
||||||
|
call BAT_CHECK_LABEL ; GOTO labels / search
|
||||||
|
RET C
|
||||||
;ld ix,T96AC ; 㦮?? § ª®¬¥â ਫ (inline.asm)
|
;ld ix,T96AC ; 㦮?? § ª®¬¥â ਫ (inline.asm)
|
||||||
;ld hl,T96AE ;;256 ¡ãä¥à (inline.asm)
|
;ld hl,T96AE ;;256 ¡ãä¥à (inline.asm)
|
||||||
ld hl,Buffers.input_line.Path
|
ld hl,Buffers.input_line.Path
|
||||||
@ -323,8 +327,10 @@ CMDMODE:
|
|||||||
ld b,a
|
ld b,a
|
||||||
inc hl ;+5
|
inc hl ;+5
|
||||||
push bc
|
push bc
|
||||||
ld c,BIOS.LP_PRINT_LINE2 ; ¢ë¢®¤ áâப¨ ¡¥§ âਡã⮢
|
LD C,Dss.PChars
|
||||||
RST ToBIOS
|
RST ToDSS
|
||||||
|
;ld c,BIOS.LP_PRINT_LINE2 ; ¢ë¢®¤ áâப¨ ¡¥§ âਡã⮢
|
||||||
|
;RST ToBIOS
|
||||||
pop bc ; b=¤«¨ áâப¨
|
pop bc ; b=¤«¨ áâப¨
|
||||||
ld a,(width_inpline) ; è¨à¨ ¯®«ï ¢¢®¤ (76..48)
|
ld a,(width_inpline) ; è¨à¨ ¯®«ï ¢¢®¤ (76..48)
|
||||||
sub b
|
sub b
|
||||||
@ -364,8 +370,10 @@ CMDMODE:
|
|||||||
;ld hl,Buffers.work.buffer+256;;
|
;ld hl,Buffers.work.buffer+256;;
|
||||||
.A826C: ld a,(hl)
|
.A826C: ld a,(hl)
|
||||||
cp " "
|
cp " "
|
||||||
|
jr z,.A826W
|
||||||
|
cp "\t"
|
||||||
jr nz,.A8276
|
jr nz,.A8276
|
||||||
inc hl
|
.A826W: inc hl
|
||||||
dec c
|
dec c
|
||||||
jr nz,.A826C
|
jr nz,.A826C
|
||||||
ret
|
ret
|
||||||
@ -377,10 +385,17 @@ CMDMODE:
|
|||||||
sbc hl,bc
|
sbc hl,bc
|
||||||
ld a,c
|
ld a,c
|
||||||
ex af,af'
|
ex af,af'
|
||||||
ld a," "
|
.A827S: ld a,c
|
||||||
cpir
|
or a
|
||||||
jr nz,.A8286
|
jr z,.A8286 ; no blank -> whole line is the command
|
||||||
inc c
|
ld a,(hl)
|
||||||
|
cp " "
|
||||||
|
jr z,.A8286
|
||||||
|
cp "\t"
|
||||||
|
jr z,.A8286
|
||||||
|
inc hl
|
||||||
|
dec c
|
||||||
|
jr .A827S
|
||||||
.A8286: ex af,af'
|
.A8286: ex af,af'
|
||||||
sub c
|
sub c
|
||||||
ld c,a ; ¤«¨ á«®¢ ¨«¨ áâப¨ ?
|
ld c,a ; ¤«¨ á«®¢ ¨«¨ áâப¨ ?
|
||||||
@ -403,7 +418,7 @@ EVALCMD: xor a
|
|||||||
call EVALSTR
|
call EVALSTR
|
||||||
ld hl,Buffers.work.buffer2 ;work_buffer+256
|
ld hl,Buffers.work.buffer2 ;work_buffer+256
|
||||||
ld de,Buffers.input_line.Path ; ªã¤
|
ld de,Buffers.input_line.Path ; ªã¤
|
||||||
ld bc,255 ;!HARDCODE
|
ld bc,max_len_comline+2
|
||||||
.loop: LD A,C
|
.loop: LD A,C
|
||||||
DEC A
|
DEC A
|
||||||
JR Z,.error
|
JR Z,.error
|
||||||
@ -413,10 +428,11 @@ EVALCMD: xor a
|
|||||||
inc b
|
inc b
|
||||||
or a
|
or a
|
||||||
jr nz,.loop
|
jr nz,.loop
|
||||||
|
;
|
||||||
dec b
|
dec b
|
||||||
ld a,b
|
ld a,b
|
||||||
ld (Buffers.input_line.Symbols_Num),a ; ¤«¨ áâப¨ (edline.asm)
|
ld (Buffers.input_line.Symbols_Num),a ; ¤«¨ áâப¨ (edline.asm)
|
||||||
and a
|
;and a
|
||||||
ret
|
ret
|
||||||
;
|
;
|
||||||
.error: LD (DE),A
|
.error: LD (DE),A
|
||||||
@ -507,6 +523,10 @@ EVALSTR: ld a,(hl)
|
|||||||
BATLIST: DZ 'PAUSE' : DW cmd_pause
|
BATLIST: DZ 'PAUSE' : DW cmd_pause
|
||||||
DZ 'REM' : DW cmd_rem
|
DZ 'REM' : DW cmd_rem
|
||||||
DZ 'EXIT' : DW cmd_break
|
DZ 'EXIT' : DW cmd_break
|
||||||
|
DZ 'GOTO' : DW cmd_goto
|
||||||
|
DZ 'GOSUB' : DW cmd_gosub
|
||||||
|
DZ 'RETURN' : DW cmd_return
|
||||||
|
DZ 'IF' : DW cmd_if
|
||||||
;
|
;
|
||||||
; DSS-ª®¬ ¤ë
|
; DSS-ª®¬ ¤ë
|
||||||
CMDLIST: DZ 'CD' : DW cmd_chdir
|
CMDLIST: DZ 'CD' : DW cmd_chdir
|
||||||
|
|||||||
@ -2,7 +2,16 @@
|
|||||||
cmd_break:
|
cmd_break:
|
||||||
.sp+1: LD SP,0
|
.sp+1: LD SP,0
|
||||||
;!TODO ¢«®¦¥ë¥ bat. ¯¥à¥¤ ¢ âì ®è¨¡ªã ®¡à â® ¢ ¢ë§ë¢ î騩 bat
|
;!TODO ¢«®¦¥ë¥ bat. ¯¥à¥¤ ¢ âì ®è¨¡ªã ®¡à â® ¢ ¢ë§ë¢ î騩 bat
|
||||||
.exit: ld a,(BAT_FM) ; ¤¥áªà. bat-ä ©«
|
.exit: ld a,(goto_active) ; GOTO: label not found ?
|
||||||
|
or a
|
||||||
|
jr z,.close
|
||||||
|
xor a
|
||||||
|
ld (goto_active),a
|
||||||
|
ld de,MAIN_MSG.LABEL_NOT_FOUND
|
||||||
|
call ECHO_MESSAGE
|
||||||
|
.close: xor a
|
||||||
|
ld (gosub_sp),a ; reset GOSUB stack
|
||||||
|
ld a,(BAT_FM) ; ¤¥áªà. bat-ä ©«
|
||||||
ld c,Dss.Close ; § ªàëâì ä ©«
|
ld c,Dss.Close ; § ªàëâì ä ©«
|
||||||
RST ToDSS
|
RST ToDSS
|
||||||
xor a
|
xor a
|
||||||
|
|||||||
277
SHELL/Commands/GOTO.ASM
Normal file
277
SHELL/Commands/GOTO.ASM
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
; !FIXIT Vibe-code ¯à®¢¥à¨âì
|
||||||
|
|
||||||
|
;///////////////////////////////////////////////////
|
||||||
|
;
|
||||||
|
; GOTO / GOSUB / RETURN. Jumps inside a BAT-file by
|
||||||
|
; ":label", MS-DOS / 4DOS style.
|
||||||
|
;
|
||||||
|
; GOTO label - jump to ":label"
|
||||||
|
; GOSUB label - call subroutine at ":label"
|
||||||
|
; RETURN - return to the line after the GOSUB
|
||||||
|
;
|
||||||
|
;///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GOTO_LABEL_MAX EQU 15 ; max label name length
|
||||||
|
GOSUB_MAX EQU 16 ; max GOSUB nesting depth
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; GOTO label
|
||||||
|
; in: de -> argument string (label, may start with ':')
|
||||||
|
;-------------------------------------------------
|
||||||
|
cmd_goto:
|
||||||
|
ex de,hl ; hl -> argument text
|
||||||
|
call GOTO_PARSE ; -> goto_label (upper, 0-term)
|
||||||
|
ld a,(goto_label)
|
||||||
|
or a
|
||||||
|
jp z,.empty ; no label name
|
||||||
|
jp GOTO_START ; rewind + start the label search
|
||||||
|
.empty: ld de,MAIN_MSG.LABEL_NOT_FOUND
|
||||||
|
jp gAbort
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; GOSUB label
|
||||||
|
; in: de -> argument string (label, may start with ':')
|
||||||
|
;-------------------------------------------------
|
||||||
|
cmd_gosub:
|
||||||
|
ex de,hl ; hl -> argument text
|
||||||
|
call GOTO_PARSE ; -> goto_label (saved in memory)
|
||||||
|
ld a,(goto_label)
|
||||||
|
or a
|
||||||
|
jp z,cmd_goto.empty
|
||||||
|
call GOSUB_PUSH ; remember the return position
|
||||||
|
jp GOTO_START ; then jump like GOTO
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; RETURN - resume after the matching GOSUB
|
||||||
|
;-------------------------------------------------
|
||||||
|
cmd_return:
|
||||||
|
ld a,(gosub_sp)
|
||||||
|
or a
|
||||||
|
jr z,.empty ; RETURN without GOSUB
|
||||||
|
dec a
|
||||||
|
ld (gosub_sp),a
|
||||||
|
add a,a
|
||||||
|
add a,a ; a = sp*4 (byte offset in stack)
|
||||||
|
ld e,a
|
||||||
|
ld d,0
|
||||||
|
ld hl,gosub_stk
|
||||||
|
add hl,de
|
||||||
|
ld e,(hl) ; saved offset (low word)
|
||||||
|
inc hl
|
||||||
|
ld d,(hl)
|
||||||
|
inc hl
|
||||||
|
ld (gosub_lo),de
|
||||||
|
ld e,(hl) ; saved offset (high word)
|
||||||
|
inc hl
|
||||||
|
ld d,(hl)
|
||||||
|
ld (gosub_hi),de
|
||||||
|
ld a,(BAT_FM) ; bat-file handle
|
||||||
|
ld hl,(gosub_hi) ; HL = offset high 16 bits
|
||||||
|
ld ix,(gosub_lo) ; IX = offset low 16 bits
|
||||||
|
ld bc,Dss.Move_FP.FrStart ; B=0 (from start), C=#15
|
||||||
|
RST ToDSS
|
||||||
|
jr c,.io
|
||||||
|
xor a
|
||||||
|
ld (MOVWORD.count),a ; force re-read from saved position
|
||||||
|
ret ; back to NEWLINE -> line after GOSUB
|
||||||
|
.empty: ld de,MAIN_MSG.RET_NO_GOSUB
|
||||||
|
jp gAbort
|
||||||
|
.io: call print_err_message
|
||||||
|
jp gAbort.silent
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Parse a label argument into goto_label
|
||||||
|
; in: hl -> text (optional spaces/TAB, optional ':')
|
||||||
|
; out: goto_label = upper-cased, 0-terminated token
|
||||||
|
;-------------------------------------------------
|
||||||
|
GOTO_PARSE:
|
||||||
|
.sp0: ld a,(hl) ; skip leading blanks (space / TAB)
|
||||||
|
cp " "
|
||||||
|
jr z,.sp0i
|
||||||
|
cp "\t"
|
||||||
|
jr nz,.nosp0
|
||||||
|
.sp0i: inc hl
|
||||||
|
jr .sp0
|
||||||
|
.nosp0: cp ":" ; allow "GOTO :label"
|
||||||
|
jr nz,.sp1
|
||||||
|
inc hl
|
||||||
|
.sp1: ld a,(hl) ; skip blanks after ':'
|
||||||
|
cp " "
|
||||||
|
jr z,.sp1i
|
||||||
|
cp "\t"
|
||||||
|
jr nz,.copy
|
||||||
|
.sp1i: inc hl
|
||||||
|
jr .sp1
|
||||||
|
.copy: ld de,goto_label
|
||||||
|
ld b,GOTO_LABEL_MAX
|
||||||
|
.cloop: ld a,(hl)
|
||||||
|
cp " "+1 ; a <= ' ' -> end of token
|
||||||
|
jr c,.cend
|
||||||
|
call COMPARE.cmp_AZ ; -> upper case
|
||||||
|
ld (de),a
|
||||||
|
inc hl
|
||||||
|
inc de
|
||||||
|
djnz .cloop
|
||||||
|
.cend: xor a
|
||||||
|
ld (de),a ; 0-terminate
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Rewind the BAT-file and start the label search
|
||||||
|
;-------------------------------------------------
|
||||||
|
GOTO_START:
|
||||||
|
ld a,(BAT_FM) ; bat-file handle
|
||||||
|
ld hl,0 ; offset low
|
||||||
|
ld ix,0 ; offset high
|
||||||
|
ld bc,Dss.Move_FP.FrStart ; B=0 (from start), C=#15
|
||||||
|
RST ToDSS
|
||||||
|
jr c,.io
|
||||||
|
xor a
|
||||||
|
ld (MOVWORD.count),a ; invalidate NEWLINE read buffer
|
||||||
|
ld a,1
|
||||||
|
ld (goto_active),a ; activate the label search
|
||||||
|
ret
|
||||||
|
.io: call print_err_message
|
||||||
|
jp gAbort.silent
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Push the return position (file offset of the line
|
||||||
|
; that follows the current GOSUB) onto the stack.
|
||||||
|
;-------------------------------------------------
|
||||||
|
GOSUB_PUSH:
|
||||||
|
ld a,(gosub_sp)
|
||||||
|
cp GOSUB_MAX
|
||||||
|
jr nc,.deep ; stack overflow
|
||||||
|
; current file pointer (tell): FrCurrent, offset 0
|
||||||
|
ld a,(BAT_FM)
|
||||||
|
ld hl,0
|
||||||
|
ld ix,0
|
||||||
|
ld bc,Dss.Move_FP.FrCurrent ; B=1, C=#15
|
||||||
|
RST ToDSS
|
||||||
|
jr c,.io
|
||||||
|
; on return: IX = pointer low 16, HL = pointer high 16
|
||||||
|
ld (gosub_hi),hl ; save high word
|
||||||
|
push ix
|
||||||
|
pop hl ; hl = pointer low 16
|
||||||
|
; offset = pointer - (bytes still unparsed in buffer1)
|
||||||
|
ld a,(MOVWORD.count)
|
||||||
|
ld e,a
|
||||||
|
ld d,0
|
||||||
|
or a ; CF=0
|
||||||
|
sbc hl,de ; hl = low - count
|
||||||
|
ld (gosub_lo),hl
|
||||||
|
jr nc,.nob
|
||||||
|
ld hl,(gosub_hi) ; borrow into high word
|
||||||
|
dec hl
|
||||||
|
ld (gosub_hi),hl
|
||||||
|
.nob:
|
||||||
|
; store at gosub_stk[gosub_sp]
|
||||||
|
ld a,(gosub_sp)
|
||||||
|
ld c,a ; c = old depth
|
||||||
|
add a,a
|
||||||
|
add a,a ; a = sp*4
|
||||||
|
ld e,a
|
||||||
|
ld d,0
|
||||||
|
ld hl,gosub_stk
|
||||||
|
add hl,de
|
||||||
|
ld de,(gosub_lo)
|
||||||
|
ld (hl),e
|
||||||
|
inc hl
|
||||||
|
ld (hl),d
|
||||||
|
inc hl
|
||||||
|
ld de,(gosub_hi)
|
||||||
|
ld (hl),e
|
||||||
|
inc hl
|
||||||
|
ld (hl),d
|
||||||
|
ld a,c
|
||||||
|
inc a
|
||||||
|
ld (gosub_sp),a ; depth++
|
||||||
|
ret
|
||||||
|
.deep: ld de,MAIN_MSG.GOSUB_DEEP
|
||||||
|
jp gAbort
|
||||||
|
.io: call print_err_message
|
||||||
|
jp gAbort.silent
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Print message (de=index) and abort the BAT-file
|
||||||
|
;-------------------------------------------------
|
||||||
|
gAbort:
|
||||||
|
call ECHO_MESSAGE
|
||||||
|
.silent:
|
||||||
|
xor a
|
||||||
|
ld (goto_active),a ; don't double-print in cmd_break.exit
|
||||||
|
jp cmd_break.exit
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Called from CMDMODE for every BAT-file line.
|
||||||
|
; Handles ":label" lines and the GOTO/GOSUB search.
|
||||||
|
;
|
||||||
|
; out: CF=1 - skip this line (label line, or searching)
|
||||||
|
; CF=0 - execute this line normally
|
||||||
|
;-------------------------------------------------
|
||||||
|
BAT_CHECK_LABEL:
|
||||||
|
ld hl,Buffers.input_line.Path
|
||||||
|
.sp: ld a,(hl) ; skip leading blanks (space / TAB)
|
||||||
|
cp " "
|
||||||
|
jr z,.spi
|
||||||
|
cp "\t"
|
||||||
|
jr nz,.first
|
||||||
|
.spi: inc hl
|
||||||
|
jr .sp
|
||||||
|
.first: cp ":" ; is it a label line ?
|
||||||
|
jr z,.label
|
||||||
|
; not a label line
|
||||||
|
ld a,(goto_active)
|
||||||
|
or a
|
||||||
|
ret z ; CF=0 -> run normally
|
||||||
|
scf ; searching -> skip line
|
||||||
|
ret
|
||||||
|
;
|
||||||
|
.label: ld a,(goto_active)
|
||||||
|
or a
|
||||||
|
jr nz,.match
|
||||||
|
; not searching: ":label" -> skip (no echo, no exec)
|
||||||
|
scf
|
||||||
|
ret
|
||||||
|
; searching: does this label match goto_label ?
|
||||||
|
.match: inc hl ; skip ':'
|
||||||
|
.msp: ld a,(hl) ; skip blanks after ':'
|
||||||
|
cp " "
|
||||||
|
jr z,.mspi
|
||||||
|
cp "\t"
|
||||||
|
jr nz,.mcmp
|
||||||
|
.mspi: inc hl
|
||||||
|
jr .msp
|
||||||
|
.mcmp: ld de,goto_label
|
||||||
|
.mlp: ld a,(de) ; target char (upper, 0-term)
|
||||||
|
or a
|
||||||
|
jr z,.mend ; target consumed
|
||||||
|
ld c,a
|
||||||
|
ld a,(hl)
|
||||||
|
cp " "+1 ; line token ended too early ?
|
||||||
|
jr c,.skip ; -> no match
|
||||||
|
call COMPARE.cmp_AZ
|
||||||
|
cp c
|
||||||
|
jr nz,.skip
|
||||||
|
inc hl
|
||||||
|
inc de
|
||||||
|
jr .mlp
|
||||||
|
.mend: ld a,(hl) ; target ended: line token must end here
|
||||||
|
cp " "+1 ; a <= ' ' -> full match
|
||||||
|
jr nc,.skip ; line label is longer -> no match
|
||||||
|
; match ! stop searching, skip the label line itself
|
||||||
|
xor a
|
||||||
|
ld (goto_active),a
|
||||||
|
scf
|
||||||
|
ret
|
||||||
|
;
|
||||||
|
.skip: scf ; keep searching, skip this line
|
||||||
|
ret
|
||||||
|
;
|
||||||
|
|
||||||
|
goto_active: db 0 ; 1 = searching for a label
|
||||||
|
goto_label: ds GOTO_LABEL_MAX+1,0 ; target label (upper, 0-term)
|
||||||
|
gosub_sp: db 0 ; GOSUB nesting depth
|
||||||
|
gosub_lo: dw 0 ; scratch (offset low)
|
||||||
|
gosub_hi: dw 0 ; scratch (offset high)
|
||||||
|
gosub_stk: ds GOSUB_MAX*4,0 ; return offsets (32-bit each)
|
||||||
241
SHELL/Commands/IF.ASM
Normal file
241
SHELL/Commands/IF.ASM
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
;///////////////////////////////////////////////////
|
||||||
|
;
|
||||||
|
; IF - conditional command (MS-DOS style)
|
||||||
|
;
|
||||||
|
; IF [NOT] ERRORLEVEL number command
|
||||||
|
; IF [NOT] EXIST filename command
|
||||||
|
; IF [NOT] string1 == string2 command
|
||||||
|
;
|
||||||
|
; If the condition is true, the rest of the line is
|
||||||
|
; executed as an ordinary command (GOTO, ECHO, a
|
||||||
|
; program, another IF, ...).
|
||||||
|
;
|
||||||
|
;///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
; in: de -> argument string (everything after "IF ")
|
||||||
|
cmd_if:
|
||||||
|
ex de,hl ; hl -> args
|
||||||
|
xor a
|
||||||
|
ld (.neg),a
|
||||||
|
call IF_SKIPB ; skip leading blanks
|
||||||
|
; --- optional NOT ---
|
||||||
|
ld de,.kw_not
|
||||||
|
call IF_KW
|
||||||
|
jr nc,.noNOT
|
||||||
|
ld a,1
|
||||||
|
ld (.neg),a
|
||||||
|
.noNOT:
|
||||||
|
; --- ERRORLEVEL n ? ---
|
||||||
|
ld de,.kw_errlvl
|
||||||
|
call IF_KW
|
||||||
|
jr nc,.notErr
|
||||||
|
ld de,Buffers.work.buffer1
|
||||||
|
ld c,Dss.GSwitch ; extract the number token
|
||||||
|
RST ToDSS
|
||||||
|
ld (.cmd),hl ; rest of line = command part
|
||||||
|
ld de,Buffers.work.buffer1
|
||||||
|
call IF_ATOI8 ; a = number (0..255)
|
||||||
|
ld b,a ; b = threshold
|
||||||
|
ld c,Dss.Get_Err ; a = exit code of last program
|
||||||
|
RST ToDSS
|
||||||
|
cp b ; A >= n ? (NC = yes)
|
||||||
|
ld a,0
|
||||||
|
jr c,.decide ; A < n -> false
|
||||||
|
inc a ; true
|
||||||
|
jr .decide
|
||||||
|
.notErr:
|
||||||
|
; --- EXIST filename ? ---
|
||||||
|
ld de,.kw_exist
|
||||||
|
call IF_KW
|
||||||
|
jr nc,.strcmp
|
||||||
|
ld de,Buffers.work.buffer1
|
||||||
|
ld c,Dss.GSwitch ; extract the filename token
|
||||||
|
RST ToDSS
|
||||||
|
ld (.cmd),hl ; rest of line = command part
|
||||||
|
ld a,FAT_ATTR.NoVolID ; any file/dir (not the volume label)
|
||||||
|
ld hl,Buffers.work.buffer1 ; filespec (NUL-term DOS name)
|
||||||
|
ld de,Buffers.work.buffer2 ; F_First work buffer
|
||||||
|
ld bc,Dss.F_First.DOSname ; B=1, C=#19
|
||||||
|
RST ToDSS
|
||||||
|
ld a,0
|
||||||
|
jr c,.decide ; CF=1 -> not found -> false
|
||||||
|
inc a ; exists -> true
|
||||||
|
jr .decide
|
||||||
|
.strcmp:
|
||||||
|
; hl -> string1 "==" string2 [blank] command
|
||||||
|
push hl ; s1 start
|
||||||
|
.find: ld a,(hl)
|
||||||
|
or a
|
||||||
|
jr z,.bad ; no "==" -> malformed
|
||||||
|
cp "="
|
||||||
|
jr nz,.fnext
|
||||||
|
inc hl
|
||||||
|
ld a,(hl)
|
||||||
|
cp "="
|
||||||
|
jr z,.foundEq
|
||||||
|
dec hl
|
||||||
|
.fnext: inc hl
|
||||||
|
jr .find
|
||||||
|
.bad: pop hl
|
||||||
|
ret ; syntax error -> no-op
|
||||||
|
.foundEq:
|
||||||
|
dec hl ; hl -> first '=' of "=="
|
||||||
|
pop de ; de = s1 start
|
||||||
|
push de
|
||||||
|
or a
|
||||||
|
sbc hl,de ; hl = len1 (line < 256 -> h=0)
|
||||||
|
ld a,l
|
||||||
|
ld (.len1),a
|
||||||
|
pop de ; de = s1 start
|
||||||
|
ld hl,0
|
||||||
|
ld l,a
|
||||||
|
add hl,de ; hl = s1 + len1 = first '='
|
||||||
|
inc hl
|
||||||
|
inc hl ; hl = s2 start
|
||||||
|
ld (.s2),hl
|
||||||
|
ld b,0 ; len2
|
||||||
|
.s2l: ld a,(hl)
|
||||||
|
cp " "+1 ; <=' ' (space/tab/CR/0) -> token end
|
||||||
|
jr c,.s2e
|
||||||
|
inc hl
|
||||||
|
inc b
|
||||||
|
jr .s2l
|
||||||
|
.s2e: ld (.cmd),hl ; command part starts here
|
||||||
|
ld a,(.len1)
|
||||||
|
cp b ; len1 == len2 ?
|
||||||
|
jr nz,.neq
|
||||||
|
or a
|
||||||
|
jr z,.eq ; both empty -> equal
|
||||||
|
ld c,a ; c = length
|
||||||
|
ld hl,(.s2)
|
||||||
|
.cl: ld a,(de) ; de = s1
|
||||||
|
cp (hl) ; case-sensitive (MS-DOS)
|
||||||
|
jr nz,.neq
|
||||||
|
inc de
|
||||||
|
inc hl
|
||||||
|
dec c
|
||||||
|
jr nz,.cl
|
||||||
|
.eq: ld a,1
|
||||||
|
jr .decide
|
||||||
|
.neq: xor a
|
||||||
|
;
|
||||||
|
.decide:
|
||||||
|
; a = raw condition (0/1)
|
||||||
|
ld b,a
|
||||||
|
ld a,(.neg)
|
||||||
|
xor b ; cond ^ NOT
|
||||||
|
and 1
|
||||||
|
ret z ; false -> nothing to do
|
||||||
|
ld hl,(.cmd)
|
||||||
|
jp IF_RUN ; true -> run the command part
|
||||||
|
;
|
||||||
|
.kw_not: db "NOT",0
|
||||||
|
.kw_errlvl: db "ERRORLEVEL",0
|
||||||
|
.kw_exist: db "EXIST",0
|
||||||
|
.neg: db 0
|
||||||
|
.cmd: dw 0
|
||||||
|
.len1: db 0
|
||||||
|
.s2: dw 0
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Skip blanks (space / TAB) at (hl)
|
||||||
|
;-------------------------------------------------
|
||||||
|
IF_SKIPB:
|
||||||
|
.l: ld a,(hl)
|
||||||
|
cp " "
|
||||||
|
jr z,.i
|
||||||
|
cp "\t"
|
||||||
|
ret nz
|
||||||
|
.i: inc hl
|
||||||
|
jr .l
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Case-insensitive keyword test.
|
||||||
|
; in: hl -> text, de -> keyword (UPPER, 0-term)
|
||||||
|
; out: CF=1 - matched, hl past keyword + blanks
|
||||||
|
; CF=0 - no match, hl unchanged
|
||||||
|
;-------------------------------------------------
|
||||||
|
IF_KW: push hl
|
||||||
|
.l: ld a,(de)
|
||||||
|
or a
|
||||||
|
jr z,.kend ; keyword consumed
|
||||||
|
ld c,a
|
||||||
|
ld a,(hl)
|
||||||
|
call COMPARE.cmp_AZ ; -> upper
|
||||||
|
cp c
|
||||||
|
jr nz,.no
|
||||||
|
inc hl
|
||||||
|
inc de
|
||||||
|
jr .l
|
||||||
|
.kend: ld a,(hl) ; must be a blank delimiter
|
||||||
|
cp " "
|
||||||
|
jr z,.ok
|
||||||
|
cp "\t"
|
||||||
|
jr z,.ok
|
||||||
|
.no: pop hl ; restore, no match
|
||||||
|
or a ; CF=0
|
||||||
|
ret
|
||||||
|
.ok: inc hl ; skip delimiter + following blanks
|
||||||
|
.ok2: ld a,(hl)
|
||||||
|
cp " "
|
||||||
|
jr z,.oki
|
||||||
|
cp "\t"
|
||||||
|
jr nz,.done
|
||||||
|
.oki: inc hl
|
||||||
|
jr .ok2
|
||||||
|
.done: pop bc ; discard saved hl
|
||||||
|
scf
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; ASCII decimal -> A (0..255, saturating)
|
||||||
|
; in: de -> digits
|
||||||
|
;-------------------------------------------------
|
||||||
|
IF_ATOI8:
|
||||||
|
ld hl,0
|
||||||
|
.l: ld a,(de)
|
||||||
|
sub "0"
|
||||||
|
jr c,.end
|
||||||
|
cp 10
|
||||||
|
jr nc,.end
|
||||||
|
ld c,a ; c = digit
|
||||||
|
ld b,0
|
||||||
|
push de
|
||||||
|
ld d,h
|
||||||
|
ld e,l
|
||||||
|
add hl,hl ; *2
|
||||||
|
add hl,hl ; *4
|
||||||
|
add hl,de ; *5
|
||||||
|
add hl,hl ; *10
|
||||||
|
add hl,bc ; + digit
|
||||||
|
pop de
|
||||||
|
inc de
|
||||||
|
jr .l
|
||||||
|
.end: ld a,h
|
||||||
|
or a
|
||||||
|
jr nz,.sat
|
||||||
|
ld a,l
|
||||||
|
ret
|
||||||
|
.sat: ld a,255
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-------------------------------------------------
|
||||||
|
; Run the conditional command.
|
||||||
|
; in: hl -> command text (NUL-term at line end)
|
||||||
|
;-------------------------------------------------
|
||||||
|
IF_RUN:
|
||||||
|
call IF_SKIPB
|
||||||
|
ld a,(hl)
|
||||||
|
or a
|
||||||
|
ret z ; empty -> no-op
|
||||||
|
ld d,h
|
||||||
|
ld e,l ; de = command start
|
||||||
|
ld bc,0 ; b=0, c = token length
|
||||||
|
.tl: ld a,(hl)
|
||||||
|
cp " "+1 ; <=' ' -> end of command token
|
||||||
|
jr c,.tle
|
||||||
|
inc hl
|
||||||
|
inc c
|
||||||
|
jr .tl
|
||||||
|
.tle: ld hl,BATLIST ; bat + dos commands
|
||||||
|
jp COMP.start ; dispatch (recurses for nested IF)
|
||||||
@ -57,6 +57,7 @@ input_line:
|
|||||||
ld (cursor_position),de ; Y/X ¯®§¨æ¨ï ªãàá®à
|
ld (cursor_position),de ; Y/X ¯®§¨æ¨ï ªãàá®à
|
||||||
call clear_inpline ; ®ç¨áâ¨âì áâàãªâãàã ~input line~
|
call clear_inpline ; ®ç¨áâ¨âì áâàãªâãàã ~input line~
|
||||||
call print_compath ; ¢ë¢¥á⨠¯ãâì + ®¢ ï è¨à¨ ¯®«ï ¢¢®¤
|
call print_compath ; ¢ë¢¥á⨠¯ãâì + ®¢ ï è¨à¨ ¯®«ï ¢¢®¤
|
||||||
|
call print_inpline
|
||||||
jp event_input_line ; ®¡à ¡. áâப¨ ¢¢®¤
|
jp event_input_line ; ®¡à ¡. áâப¨ ¢¢®¤
|
||||||
|
|
||||||
|
|
||||||
@ -98,6 +99,7 @@ print_compath:
|
|||||||
ld a,">"
|
ld a,">"
|
||||||
ld bc,1*256 + BIOS.LP_PRINT_SYM ; ᨬ¢®« ¡¥§ âਡãâ
|
ld bc,1*256 + BIOS.LP_PRINT_SYM ; ᨬ¢®« ¡¥§ âਡãâ
|
||||||
RST ToBIOS
|
RST ToBIOS
|
||||||
|
RET
|
||||||
;jr print_inpline ; ¢ë¢®¤ áâப¨ ¢¢®¤
|
;jr print_inpline ; ¢ë¢®¤ áâப¨ ¢¢®¤
|
||||||
;-------------------------------------------------
|
;-------------------------------------------------
|
||||||
; ‚뢮¤ áâப¨ ~input line~ íªà
|
; ‚뢮¤ áâப¨ ~input line~ íªà
|
||||||
@ -156,7 +158,7 @@ print_inpline:
|
|||||||
ld e,(iy + Input_Line.Cur_X) ;+2 ⥪. ¯®«®¦. ªãàá®à ¢ áâப¥
|
ld e,(iy + Input_Line.Cur_X) ;+2 ⥪. ¯®«®¦. ªãàá®à ¢ áâப¥
|
||||||
add a,e
|
add a,e
|
||||||
cp width_inpline.MAX ; è¨à¨ íªà
|
cp width_inpline.MAX ; è¨à¨ íªà
|
||||||
jr c,prne1__
|
jr c,.prne1
|
||||||
ld b,width_inpline.MAX-1
|
ld b,width_inpline.MAX-1
|
||||||
sub b
|
sub b
|
||||||
ld d,a ; " ¥§¤" § ¯à ¢ë© ªà ©
|
ld d,a ; " ¥§¤" § ¯à ¢ë© ªà ©
|
||||||
@ -164,7 +166,7 @@ print_inpline:
|
|||||||
sub d
|
sub d
|
||||||
ld (iy + Input_Line.Cur_X),a ;+2 ®¢®¥ ¯®«®¦. ªãàá®à
|
ld (iy + Input_Line.Cur_X),a ;+2 ®¢®¥ ¯®«®¦. ªãàá®à
|
||||||
ld a,b
|
ld a,b
|
||||||
prne1__:ld (cursor_position),a ; X ¯®«®¦. ªãàá®à íªà ¥
|
.prne1: ld (cursor_position),a ; X ¯®«®¦. ªãàá®à íªà ¥
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ¢å®¤: HL - ¯®«ë© ¯ãâì
|
; ¢å®¤: HL - ¯®«ë© ¯ãâì
|
||||||
@ -367,7 +369,7 @@ inpline_work:
|
|||||||
add a,(iy + Input_Line.Left_Shift)
|
add a,(iy + Input_Line.Left_Shift)
|
||||||
cp (iy + Input_Line.max_Len)
|
cp (iy + Input_Line.max_Len)
|
||||||
;ret nc
|
;ret nc
|
||||||
JR NC,LastChar_BEEP
|
JR NC,NoMoreChars_BEEP
|
||||||
bit 7,(iy + Input_Line.ReadyString)
|
bit 7,(iy + Input_Line.ReadyString)
|
||||||
;ret nz
|
;ret nz
|
||||||
JR NZ,NoMoreChars_BEEP
|
JR NZ,NoMoreChars_BEEP
|
||||||
@ -424,22 +426,34 @@ no_insert:
|
|||||||
pop de ; ¢®ááâ. ¡ « á á⥪
|
pop de ; ¢®ááâ. ¡ « á á⥪
|
||||||
input_line_done:
|
input_line_done:
|
||||||
ret
|
ret
|
||||||
LastChar_BEEP:
|
; LastChar_BEEP:
|
||||||
;!TODO ¥á«¨ ᨬ¢®«ë ¯à¨¢ëᨫ¨ ¬ ªá¨¬ «ì®¥ ç¨á«®, â® íªà ¥
|
; ; ¥á«¨ ᨬ¢®«ë ¯à¨¢ëᨫ¨ ¬ ªá¨¬ «ì®¥ ç¨á«®, â® íªà ¥
|
||||||
; ¢ áâப¥ ®áâ ñâáï íå® ¦ ⮩ ª« ¢¨è¨, ª®â®à ï ¥ ¢«¥§«
|
; ; ¢ áâப¥ ®áâ ñâáï íå® ¦ ⮩ ª« ¢¨è¨, ª®â®à ï ¥ ¢«¥§«
|
||||||
; ¨ ¢¨á¨â ¤® ¦ â¨ï ®ç¥à¥¤®© ª« ¢¨è¨. ˆá¯à ¢¨âì.
|
; ; ¨ ¢¨á¨â ¤® ¦ â¨ï ®ç¥à¥¤®© ª« ¢¨è¨. ˆá¯à ¢¨âì.
|
||||||
LD A,7 ;ASCII BELL
|
; LD A,7 ;ASCII BELL
|
||||||
LD C,Dss.PutChar
|
; LD C,Dss.PutChar
|
||||||
JP ToDSS
|
; JP ToDSS
|
||||||
|
|
||||||
|
;!FIXIT SCROLL ᤥ« âì 㦥 äãªæ¨¨ ¤®á ¤«ï ¯¥ç ⨠¢ ª®á®«ì ¡¥§ áªà®««
|
||||||
NoMoreChars_BEEP:
|
NoMoreChars_BEEP:
|
||||||
;!TODO ¥á«¨ ᨬ¢®«ë ¯à¨¢ëᨫ¨ ¬ ªá¨¬ «ì®¥ ç¨á«®, â® íªà ¥
|
;!TODO ¥á«¨ ᨬ¢®«ë ¯à¨¢ëᨫ¨ ¬ ªá¨¬ «ì®¥ ç¨á«®, â® íªà ¥
|
||||||
; ¢ áâப¥ ®áâ ñâáï íå® ¦ ⮩ ª« ¢¨è¨, ª®â®à ï ¥ ¢«¥§«
|
; ¢ áâப¥ ®áâ ñâáï íå® ¦ ⮩ ª« ¢¨è¨, ª®â®à ï ¥ ¢«¥§«
|
||||||
; ¨ ¢¨á¨â ¤® ¦ â¨ï ®ç¥à¥¤®© ª« ¢¨è¨. ˆá¯à ¢¨âì.
|
; ¨ ¢¨á¨â ¤® ¦ â¨ï ®ç¥à¥¤®© ª« ¢¨è¨. ˆá¯à ¢¨âì.
|
||||||
LD A,7 ;ASCII BELL
|
LD DE,(cursor_position)
|
||||||
|
LD C,Dss.Locate
|
||||||
|
RST ToDSS
|
||||||
|
PUSH DE
|
||||||
|
LD C,Dss.RdChar
|
||||||
|
RST ToDSS ; A - ᨬ¢®«, B - âਡãâ
|
||||||
|
POP DE
|
||||||
|
LD A,' ' ; ᨬ¢®«
|
||||||
|
LD C,Dss.WrChar ; #58
|
||||||
|
RST ToDSS
|
||||||
|
LD A,7 ;ASCII BELL
|
||||||
LD C,Dss.PutChar
|
LD C,Dss.PutChar
|
||||||
JP ToDSS
|
JP ToDSS
|
||||||
|
|
||||||
|
|
||||||
; ‘®¡ë⨥ - ªãàá. ª« ¢¨è¨ ¨«¨ ª®¬¡¨ 樨
|
; ‘®¡ë⨥ - ªãàá. ª« ¢¨è¨ ¨«¨ ª®¬¡¨ 樨
|
||||||
EvComComb:
|
EvComComb:
|
||||||
ld b,(hl) ;+1 what
|
ld b,(hl) ;+1 what
|
||||||
|
|||||||
@ -8,8 +8,8 @@ SAVEHL: dw 0
|
|||||||
;-------------------------------------------------------------
|
;-------------------------------------------------------------
|
||||||
COMP: call EVALCMD ; (batch.asm)
|
COMP: call EVALCMD ; (batch.asm)
|
||||||
RET C
|
RET C
|
||||||
ld hl,Buffers.input_line.Path
|
ld hl,Buffers.input_line.Path - 1
|
||||||
dec hl
|
;dec hl
|
||||||
ld c,(hl) ; か┃<E3818B> 痰牀<E797B0>
|
ld c,(hl) ; か┃<E3818B> 痰牀<E797B0>
|
||||||
ld b,0
|
ld b,0
|
||||||
inc hl ; Buffers.input_line.Path
|
inc hl ; Buffers.input_line.Path
|
||||||
|
|||||||
@ -25,6 +25,9 @@ MAIN_MSG:
|
|||||||
.INFO_2 EQU .INFO_2_
|
.INFO_2 EQU .INFO_2_
|
||||||
.DIRPAUSE EQU .DIRPAUSE_
|
.DIRPAUSE EQU .DIRPAUSE_
|
||||||
.CLSLINE EQU .CLSLINE_
|
.CLSLINE EQU .CLSLINE_
|
||||||
|
.LABEL_NOT_FOUND EQU .LBLNF_
|
||||||
|
.RET_NO_GOSUB EQU .RNGSB_
|
||||||
|
.GOSUB_DEEP EQU .GSBDP_
|
||||||
;
|
;
|
||||||
!txtCounter DEFL 0
|
!txtCounter DEFL 0
|
||||||
; ; ¥ ᤢ¨£ âì____
|
; ; ¥ ᤢ¨£ âì____
|
||||||
@ -55,6 +58,9 @@ MAIN_MSG:
|
|||||||
stN .INFO_2_ : DZ " %9 \r\t %8\r\t\t\t %7\r\t\t\t\t\t %4\r\t\t\t\t\t\t\t %5\r\n"
|
stN .INFO_2_ : DZ " %9 \r\t %8\r\t\t\t %7\r\t\t\t\t\t %4\r\t\t\t\t\t\t\t %5\r\n"
|
||||||
stN .DIRPAUSE_ : DZ "Press ESC to cancel or any other key to continue . . .\r"
|
stN .DIRPAUSE_ : DZ "Press ESC to cancel or any other key to continue . . .\r"
|
||||||
stN .CLSLINE_ : DZ " \r"
|
stN .CLSLINE_ : DZ " \r"
|
||||||
|
stN .LBLNF_ : DZ "Label not found\r\n"
|
||||||
|
stN .RNGSB_ : DZ "RETURN without GOSUB\r\n"
|
||||||
|
stN .GSBDP_ : DZ "GOSUB nesting too deep\r\n"
|
||||||
; ;R11
|
; ;R11
|
||||||
db 0
|
db 0
|
||||||
DZ "Unknown command"
|
DZ "Unknown command"
|
||||||
|
|||||||
@ -1,17 +1,3 @@
|
|||||||
; <20>®á«¥¤ïï । ªæ¨ï: 22.10.2006
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
; - ˆá¯à ¢«¥ ä¨à¬. ¡ £, ¯à¨ ª®â®à®¬ áâப ¢ bat-ä ©«¥, ¤«¨¥¥ è¨à¨ë
|
|
||||||
; íªà , ®¡à¥§ « áì ¯® è¨à¨¥ íªà ¨ ®áâ ⮪ áâப¨ ¥ ¢ë¢®¤¨«áï.
|
|
||||||
; - ˆá¯à ¢«¥ ä¨à¬. ¡ £, ¯à¨ ª®â®à®¬ ¢ ª®¬ ¤¥ "dir" áâப ¢ë¢®¤¨¬®£®
|
|
||||||
; ¯ã⨠¨¬¥« ¬ ªá. 15 ᨬ¢®«®¢.
|
|
||||||
; - <20>®ä¨ªá¥® ¥¢¥à®¥ ¨§¬¥¥¨¥ ¤¨áª /¯ã⨠¯®á«¥ ®è¨¡®ª ¢ë¯®«¥¨ï ª®¬ ¤.
|
|
||||||
; - „®¡ ¢«¥ ª®¬ ¤ "ECHO." ¤«ï ¢áâ ¢ª¨ ¯ãá⮩ áâப¨.
|
|
||||||
; - Š®¬ ¤ DIR ¢ë¢®¤¨â ¬¥âªã ¨ á¥à¨©ë© ®¬¥à ¤¨áª®¢.
|
|
||||||
;
|
|
||||||
;
|
|
||||||
|
|
||||||
; SYSTEM.EXE /S /P
|
; SYSTEM.EXE /S /P
|
||||||
;
|
;
|
||||||
; /P Primary command processor
|
; /P Primary command processor
|
||||||
@ -535,6 +521,8 @@ T8C24: db "OFF",0
|
|||||||
;
|
;
|
||||||
include 'Commands/exit.asm' ; ¢ë室 ¢ த¨â. ¯à®æ¥áá
|
include 'Commands/exit.asm' ; ¢ë室 ¢ த¨â. ¯à®æ¥áá
|
||||||
include 'Commands/break.asm' ; ¢ë室 ¨§ ¯ àá¥à bat
|
include 'Commands/break.asm' ; ¢ë室 ¨§ ¯ àá¥à bat
|
||||||
|
include 'Commands/goto.asm' ; GOTO - jump to a label in a bat
|
||||||
|
include 'Commands/if.asm' ; IF - conditional command
|
||||||
include 'Commands/pause.asm' ; ¯ ã§
|
include 'Commands/pause.asm' ; ¯ ã§
|
||||||
include 'Commands/rem.asm' ; ª®¬¬¥â ਩
|
include 'Commands/rem.asm' ; ª®¬¬¥â ਩
|
||||||
include 'Commands/ver.asm' ; ¢ë¢®¤ ¢¥àᨨ „Ž‘
|
include 'Commands/ver.asm' ; ¢ë¢®¤ ¢¥àᨨ „Ž‘
|
||||||
@ -553,6 +541,12 @@ T8C24: db "OFF",0
|
|||||||
include 'Commands/set.asm' ; § ¤ âì ¯¥à¥¬¥ãî ®ªà㦥¨ï
|
include 'Commands/set.asm' ; § ¤ âì ¯¥à¥¬¥ãî ®ªà㦥¨ï
|
||||||
include 'Commands/reboot.asm' ; á®äâ à¥á¥â
|
include 'Commands/reboot.asm' ; á®äâ à¥á¥â
|
||||||
;
|
;
|
||||||
|
DISPLAY "bat_params: ",/H,Buffers.bat_params, ". Size: ",/H, BAT_PARAMS, " End: ",/H, Buffers.bat_params + BAT_PARAMS - 1
|
||||||
|
DISPLAY "screen_path: ",/H,Buffers.screen_path, ". Size: ",/H, 2 + max_screen_path + 1, " End: ",/H, Buffers.screen_path + (2 + max_screen_path + 1) - 1
|
||||||
|
DISPLAY "sys_path: ",/H,Buffers.sys_path, ". Size: ",/H, 256, " End: ",/H, Buffers.sys_path + 255
|
||||||
|
DISPLAY "input_line: ",/H,Buffers.input_line, ". Size: ",/H, Input_Line, " End: ",/H, Buffers.input_line + Input_Line - 1
|
||||||
|
DISPLAY "history: ",/H,Buffers.history, ". Size: ",/H, history_size, " End: ",/H, Buffers.history + history_size - 1
|
||||||
|
DISPLAY "work: ",/H,Buffers.work, ". Size: ",/H, Work, " End: ",/H, Buffers.work + Work - 1
|
||||||
DISPLAY "Empty space for buffers from ",/H,$
|
DISPLAY "Empty space for buffers from ",/H,$
|
||||||
DISPLAY "Free space from ",/H,$ + Struc_Buffers
|
DISPLAY "Free space from ",/H,$ + Struc_Buffers
|
||||||
assert ($ + Struc_Buffers) < (stack_point - stack_size), "Buffers can leack to stack!"
|
assert ($ + Struc_Buffers) < (stack_point - stack_size), "Buffers can leack to stack!"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
STRUCT Input_Line
|
STRUCT Input_Line
|
||||||
.max_Len BYTE 254 ;+0 254 ¬ ªá. ç¨á«® ¢¢®¤. ᨬ¢®«®¢
|
.max_Len BYTE max_len_comline ;+0 254 ¬ ªá. ç¨á«® ¢¢®¤. ᨬ¢®«®¢
|
||||||
.ReadyString BYTE 0 ;+1 ä« £ ReadyString
|
.ReadyString BYTE 0 ;+1 ä« £ ReadyString
|
||||||
.Cur_X BYTE 0 ;+2 X ⥪. ¯®«®¦. ªãàá®à ¢ ¯à¥¤¥« å áâப¨
|
.Cur_X BYTE 0 ;+2 X ⥪. ¯®«®¦. ªãàá®à ¢ ¯à¥¤¥« å áâப¨
|
||||||
.Left_Shift BYTE 0 ;+3 X ᬥé. áâப¨ § «¥¢ë© ªà © (¢ ᨬ¢®« å)
|
.Left_Shift BYTE 0 ;+3 X ᬥé. áâப¨ § «¥¢ë© ªà © (¢ ᨬ¢®« å)
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit d2ba40c4620459681fdc5eb8d4cadcb50eb79aa8
|
Subproject commit 591d3212c9341f17d6dd034bf2b8da91bd2f6107
|
||||||
828
keys.md
Normal file
828
keys.md
Normal file
@ -0,0 +1,828 @@
|
|||||||
|
# Промт для новой сессии: изучение и модификация клавиатурной подсистемы DSS
|
||||||
|
|
||||||
|
## Задача
|
||||||
|
Изучить и при необходимости модифицировать алгоритмы работы с клавиатурой,
|
||||||
|
реализованные в [DSS/KEYINTER.ASM](DSS/KEYINTER.ASM) — модуле, который
|
||||||
|
включается в ядро DSS через `INCLUDE` из [DSS/DSS-MAIN.ASM](DSS/DSS-MAIN.ASM)
|
||||||
|
(строка 402, сразу после таблицы `DSS_API_TABLE`). Это код для компьютера
|
||||||
|
**Sprinter** (Z84C15), работающего как PS/2-хост для AT-клавиатуры через
|
||||||
|
встроенный в Z84C15 SIO канал A.
|
||||||
|
|
||||||
|
Перед изменениями сверяй свои выводы с исходным кодом: в этом проекте уже
|
||||||
|
зафиксирована память о том, что **доверять разбору регистров/стека от
|
||||||
|
суб-агентов нельзя** — трассируй PUSH/POP/EX AF/EXX лично (см.
|
||||||
|
`[[verify-subagent-reg-flow-claims]]` в auto-memory).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Рабочее окружение
|
||||||
|
|
||||||
|
- **Основная директория проекта** (kernel + сборка):
|
||||||
|
`/Users/tolik/Documents/SP_Projects/ASM/GIT/Estex DSS`
|
||||||
|
- **Доп. директория** (архив/референс, не собирается):
|
||||||
|
`/Users/tolik/Documents/SP_Projects/ASM/Another` (подключена в
|
||||||
|
`Estex DSS.code-workspace` как второй корень)
|
||||||
|
- **Подмодуль git**: [Shared_Includes/](Shared_Includes/) — общие
|
||||||
|
константы/структуры/доки; ветка `main`, url `../Shared_Includes.git`.
|
||||||
|
- **Кодировка/переводы строк**: исходники в **CP866 (русский DOS)** с
|
||||||
|
**CRLF**. Это включает `DSS-MAIN.ASM`, `KEYINTER.ASM` и большинство
|
||||||
|
`Shared_Includes/constants/*.inc`. `grep -aI` нужен, если grep считает
|
||||||
|
файлы бинарными.
|
||||||
|
- **Ассемблер**: `sjasmplus --syntax=afw`. Сборка идёт через VS Code
|
||||||
|
([.vscode/tasks.json](.vscode/tasks.json)) — Makefile нет. Полезные
|
||||||
|
задачи: `Build SYSTEM.DOS`, `Build SYSTEM.DOS [NEW]`
|
||||||
|
(`--define INCREASE_BUILD` → инкремент `DSS/build.txt`),
|
||||||
|
`Build SYSTEM.EXE`, `Build SYS.EXE`, `Copy all files to MAME`
|
||||||
|
(вызывает [RUN/Image.sh](RUN/Image.sh) → `hdfmonkey put` в
|
||||||
|
`/Users/tolik/Documents/MAME/IMG/test_2g.img`), `Run MAME`.
|
||||||
|
- **Выходы сборки**:
|
||||||
|
`Build/DSS/SYSTEM.DOS` (ядро),
|
||||||
|
`Build/DSS/SYSTEM.EXE` (шелл),
|
||||||
|
`Build/DSS/SYS.EXE` (бутлоадер),
|
||||||
|
`Build/DSS-MAIN.LST` (листинг ~1 МБ),
|
||||||
|
`Build/Variables.inc` (экспортированные символы через `--exp`).
|
||||||
|
- **Версия**: `VERS=1, MODF=71`, билд из `DSS/build.txt` (сейчас 68) → "DSS 1.71.68".
|
||||||
|
Логика в [DSS/VERSION.INC](DSS/VERSION.INC) + LUA в
|
||||||
|
[Shared_Includes/LUA/Functions.lua](Shared_Includes/LUA/Functions.lua).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Архитектура DSS и место KEYINTER
|
||||||
|
|
||||||
|
### 2.1. Точка входа ядра — [DSS/DSS-MAIN.ASM](DSS/DSS-MAIN.ASM)
|
||||||
|
- `ORG 0`, ядро располагается с адреса #0000 на странице ядра.
|
||||||
|
- **RST-векторы** (DSS-MAIN.ASM около строк 30-310):
|
||||||
|
- `RST 00` — RETFAR / реентри для дочерних процессов
|
||||||
|
- `RST 08` (`ToBIOS`) — портал в BIOS в SLOT0
|
||||||
|
- `RST 10` (`ToDSS`) — DSS API gateway → `RST_10` диспетчер на строке 187
|
||||||
|
- `RST 18` — портал в страницу драйверов
|
||||||
|
- `RST 20`, `RST 28` — NOPS
|
||||||
|
- `RST 30` (`ToDSS.Mouse`) — мышиный API
|
||||||
|
- `RST 38` (IM 1) — `INTx38_Handler` на строке 275: сохраняет все регистры
|
||||||
|
(главный набор + альтернативный + IX/IY), вызывает `CALL KEYSCAN`,
|
||||||
|
затем `RST ToDSS.Mouse GetPackets`, затем `cursor_interrupt`, `RETI`.
|
||||||
|
- **Диспетчер `RST_10`** (строка 187): `LD H,high DSS_API_TABLE / LD L,C` —
|
||||||
|
C=номер функции, индексирует таблицу адресов с раздельными байтами
|
||||||
|
(низкие байты строки 340-361, высокие 369-390).
|
||||||
|
- **Клавиатурные слоты в `DSS_API_TABLE`** (строки 344-345 / 373-374):
|
||||||
|
- `#30 WAITKEY`, `#31 SCANKEY`, `#32 ECHOKEY`, `#33 CTRLKEY`,
|
||||||
|
**`#34 NOPS`** (зарезервирован, не реализован — константа
|
||||||
|
`Dss.EDIT` есть, кода нет), `#35 K_CLEAR`, `#36 K_SETUP`, `#37 TESTKEY`.
|
||||||
|
- **INCLUDE KEYINTER.ASM** — строка 402.
|
||||||
|
- **Boot-флоу** `F_START` (строка 567): DEPLOY → `CALL KEYBOARD_INIT`
|
||||||
|
(строка 592) → PRINT_INIT → инициализация мыши → инициализация дисков →
|
||||||
|
`EI` → `CLEAR_BUFFER_AND_INIT_PROC`.
|
||||||
|
- **Карта памяти** ([DSS/DSS_MAP.TXT](DSS/DSS_MAP.TXT)):
|
||||||
|
- `#0000..#0038` — RESTARTS
|
||||||
|
- `#0200..#03FF` — `DSS_API_TABLE`
|
||||||
|
- `#0400..#043F` — **SBUF** (буфер клавиатуры, 64 байта)
|
||||||
|
- `#0440..#0BD1` — код KEYINTER (~1936 байт)
|
||||||
|
- `#0BD2..#0EF5` — драйвер экрана (для совместного использования с
|
||||||
|
`Cursor_On/Off`)
|
||||||
|
|
||||||
|
### 2.2. Соседние модули
|
||||||
|
- [DSS/API.asm](DSS/API.asm) — агрегатор-INCLUDE для всех `DSS/API/*.asm`.
|
||||||
|
- [DSS/FS_Module.asm](DSS/FS_Module.asm) — `FS/FAT.asm` + `FS/CDFS.ASM`.
|
||||||
|
- [DSS/DOS_Proc.asm](DSS/DOS_Proc.asm) — DOS-уровневые помощники
|
||||||
|
(имена файлов, маски, `SET_FM`, `OPENDSK` и т.п.).
|
||||||
|
- [DSS/Procedures.asm](DSS/Procedures.asm) — общие хелперы
|
||||||
|
(`PUTCHAR` строка 103, `PUTCHAR.NO_SCROLL` строка 104, `MK_TIME` и др.).
|
||||||
|
- [DSS/DRV-MAIN.ASM](DSS/DRV-MAIN.ASM) — отдельная страница драйверов
|
||||||
|
(DISP/ENT-блок в `DSS-MAIN.ASM:695-699`), своя таблица RST по адресам
|
||||||
|
`#A0000..#A0038`. Клавиатура там НЕ живёт.
|
||||||
|
- [DSS/drivers/Input/MOUSE.ASM](DSS/drivers/Input/MOUSE.ASM) — мышь;
|
||||||
|
делит окно INT 38h с KEYINTER (сначала `KEYSCAN`, потом мышь).
|
||||||
|
- [DSS/defines.inc](DSS/defines.inc) — compile-time флаги (см. §5).
|
||||||
|
- [DSS/DSS_MACROSES.Z80](DSS/DSS_MACROSES.Z80) — макросы. Закомментированный
|
||||||
|
`BUFFER_KEYINTER` (строки 2-82) задокументирован как канонический layout
|
||||||
|
`SBUF/KEYFLAG/KEYCTRL/KEYFLG/SOUND_K`, но реальные определения сейчас
|
||||||
|
inline в `KEYINTER.ASM`. `SET_PAGE_X` (строки 137-143) — рабочий макрос
|
||||||
|
переключения страниц SLOT3.
|
||||||
|
|
||||||
|
### 2.3. Внешние символы, на которые ссылается KEYINTER
|
||||||
|
| Символ | Что | Где определён |
|
||||||
|
|--------|-----|---------------|
|
||||||
|
| `PUTCHAR`, `PUTCHAR.NO_SCROLL` | вывод символа | `DSS/Procedures.asm:103-104` |
|
||||||
|
| `LOCATE` | установка курсора | `DSS/API/Locate.asm:8` |
|
||||||
|
| `VMODE` | байт текущего видеорежима | `DSS/API/SetVMod.asm:90` |
|
||||||
|
| `BANKTBL` | таблица логическая→физическая страница | `DSS/DSS-MAIN.ASM:423` |
|
||||||
|
| `RST_10` | диспетчер DSS | `DSS/DSS-MAIN.ASM:187` |
|
||||||
|
| `ToBIOS`, `BIOS.*` | BIOS API | `Shared_Includes/constants/BIOS_equ.inc` |
|
||||||
|
| `ToDSS`, `Dss.*`, `DSS_Error.*` | DSS константы | `Shared_Includes/constants/dss_equ.inc` |
|
||||||
|
| `Z84.SIO.Ch_A.{Data,Ctrl}`, `SP_SND.Beeper`, `SLOT3`, `TXTPAGE` | железо | `Shared_Includes/constants/SP2000.inc` (модуль `Z84`, строки 2111-2127); часть EQU может приходить из внешнего SP2000-инклюда не из снимка репо — проверять `Build/Variables.inc` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. KEYINTER.ASM подробно
|
||||||
|
|
||||||
|
Файл — 1371 строка, CRLF, CP866. Заголовок R01 (10.02.2003, DNS — добавлен
|
||||||
|
курсор в `ECHOKEY`) и R02 (13.04.2023, BAO — исправлен stack overflow в
|
||||||
|
`K_CLEAR`).
|
||||||
|
|
||||||
|
### 3.1. Публичный API (вызывается через `RST 10` с `C=` номер функции)
|
||||||
|
|
||||||
|
| C | Метка | Строки | Назначение |
|
||||||
|
|---|-------|--------|------------|
|
||||||
|
| #30 | `WAITKEY` | 112-119 | Блокирующее ожидание. Выход: `A=E=ASCII`, `D=` поз.код, `B=KEYCTRL`, `C=KEYFLAG` |
|
||||||
|
| #31 | `SCANKEY` | 122-128 | Неблокирующее. `ZF=1` если буфер пуст |
|
||||||
|
| #32 | `ECHOKEY` | 195-212 | `SCANKEY` + программный курсор (`Cursor_On`/`Off`), эхо через `PUTCHAR.NO_SCROLL` |
|
||||||
|
| #33 | `CTRLKEY` | 383-391 | Прочесть `BC=(KEYFLAG)` без извлечения; `A=0` если буфер пуст, `A=#FF` если есть |
|
||||||
|
| #34 | (NOPS) | — | `Dss.EDIT` определён, но функция не реализована в v1.71 |
|
||||||
|
| #35 | `K_CLEAR` | 431-445 | Очистить буфер (`HEAD:=HOST`), потом `JP RST_10` для повторной диспетчеризации, если `B ∈ [#30..#34]`. Иначе `A=#01 INVALID_FUNCTION`, `CF=1` |
|
||||||
|
| #36 | `K_SETUP` | 934-... | Мультиплексор: см. §3.6 |
|
||||||
|
| #37 | `TESTKEY` | 393-408 | Peek текущей записи без сдвига `HOST`. `ZF=1` если пуст |
|
||||||
|
|
||||||
|
### 3.2. Кольцевой буфер
|
||||||
|
- **`SBUF`** (строка 14): `_mInfoALIGN 256,0` + `BLOCK 64,0` — 64 байта на
|
||||||
|
границе страницы. Поэтому high-byte адреса слота = `high SBUF`, а
|
||||||
|
`HEAD`/`HOST` — только low-byte (0..#3F).
|
||||||
|
- **`HEAD`** (строка 33) — указатель писателя.
|
||||||
|
- **`HOST`** (строка 34) — указатель читателя.
|
||||||
|
- **Слот = 4 байта**: `byte+0=E (ASCII)`, `byte+1=D (поз.код | #80)`,
|
||||||
|
`byte+2=B (KEYCTRL snapshot)`, `byte+3=C (KEYFLAG snapshot)`.
|
||||||
|
- Макс. 16 записей.
|
||||||
|
- Пуст: `HEAD == HOST`. Полон: `HEAD == (HOST-4) & #3F` (проверка
|
||||||
|
`PUTSYM` строки 450-453).
|
||||||
|
- **`GetSymAddr`** (строки 467-476) — общий помощник: `A := (HL)`,
|
||||||
|
`INC (HL)` ×4, `RES 6,(HL)` (wrap modulo 64), формирует
|
||||||
|
`HL = high SBUF : старый offset`.
|
||||||
|
- **`PUTSYM`** (448-464) — продьюсер. На переполнении прыгает в
|
||||||
|
`FULL_BF` (496-505): если `SF_BUFF` бит SOUND_K взведён — `BEEP`
|
||||||
|
с `DE=230, HL=50`, ключ отбрасывается.
|
||||||
|
- **`GETSYM`** (479-493) — консьюмер.
|
||||||
|
|
||||||
|
### 3.3. Байты состояния (адресуются через `LD IX,KEYFLAG` на строке 519)
|
||||||
|
|
||||||
|
**`KEYFLAG`** (offset 0, alias `K_LOCK`, строка 45, init `#02` — `INS_L` on):
|
||||||
|
| Бит | Имя | Значение |
|
||||||
|
|-----|-----|---------|
|
||||||
|
| 7 | `LANG_L` | язык RUS/LAT |
|
||||||
|
| 6 | `PAUSE_L` | Pause Lock |
|
||||||
|
| 5 | `RES5_L` | резерв (в комментариях помечено как историческое `X_SHIFT`) |
|
||||||
|
| 4 | `RES4_L` | резерв |
|
||||||
|
| 3 | `NUM_L` | Num Lock |
|
||||||
|
| 2 | `SCRL_L` | Scroll Lock |
|
||||||
|
| 1 | `INS_L` | Insert |
|
||||||
|
| 0 | `CAPS_L` | Caps Lock |
|
||||||
|
|
||||||
|
Переключается: `CAPS_X` 668-671, `LANG_X` 674-690, `INS_X` 693-696,
|
||||||
|
`NUM_X` 699-702, `PAUSE_X` 705-718, `SCL_X` 721-724.
|
||||||
|
|
||||||
|
**`KEYCTRL`** (offset 1, alias `K_SHIFT`, строка 56, init `#00`):
|
||||||
|
| Бит | Имя |
|
||||||
|
|-----|-----|
|
||||||
|
| 7 | `L_SHIFT` |
|
||||||
|
| 6 | `R_SHIFT` |
|
||||||
|
| 5 | `X_CTRL` (любой Ctrl) |
|
||||||
|
| 4 | `X_ALT` (любой Alt) |
|
||||||
|
| 3 | `L_CTRL` |
|
||||||
|
| 2 | `L_ALT` |
|
||||||
|
| 1 | `R_CTRL` |
|
||||||
|
| 0 | `R_ALT` |
|
||||||
|
|
||||||
|
Устанавливаются в `SHIFTS` (799-836) на нажатии, сбрасываются в `UNSHIFT`
|
||||||
|
(738-797) на отпускании. Также чистятся в `KBD_Receiver_Overrun` (1240).
|
||||||
|
|
||||||
|
**`KEY_FLG`** (offset 2, alias `KEYFLG`, строка 67, init `#00`):
|
||||||
|
| Бит | Имя |
|
||||||
|
|-----|-----|
|
||||||
|
| 7 | `FLAG_E0` — защёлкнут E0-префикс (extended) |
|
||||||
|
| 6 | `FLAG_F0` — защёлкнут F0-префикс (release) |
|
||||||
|
| 5 | `FLAG_E1` — E1-префикс (только если `USE_E1_SCANCODE`) |
|
||||||
|
| 4-1 | резерв |
|
||||||
|
| 0 | `CTRL_SHIFT` — Ctrl+Shift зафиксирован (для `LANG_X` при `CHANGE_LANG_CTRL_SHIFT`) |
|
||||||
|
|
||||||
|
**`SOUND_K`** (offset 3, строка 78, init `#03` — оба звука включены):
|
||||||
|
| Бит | Имя |
|
||||||
|
|-----|-----|
|
||||||
|
| 7-2 | `FLAG_S7..S2`, резерв |
|
||||||
|
| 1 | `SF_ALT` — звук при смене языка |
|
||||||
|
| 0 | `SF_BUFF` — звук при переполнении буфера |
|
||||||
|
|
||||||
|
**`UNCODE`** (offset 4, WORD, строка 81) — последний отпущенный скан-код
|
||||||
|
(пишется в `UN_KEY` строка 663).
|
||||||
|
|
||||||
|
### 3.4. Таблица трансляции скан-кодов
|
||||||
|
- **`XLAT_T`** (строки 21-30) — сырая таблица 144 байта,
|
||||||
|
AT scancode (Set 2) → внутренний позиционный код 0..#5A.
|
||||||
|
`XLAT_T.Size = 144`. Bounds-check в `XLAT` на строке 860.
|
||||||
|
- **`XLAT`** (839-870) — собственно переводчик. Если защёлкнут `FLAG_E0`,
|
||||||
|
жёстко мапит специальные коды (`#11→#39 R-ALT`, `#14→#3A R-CTRL`,
|
||||||
|
`#5A→#4E numpad Enter`, `#4A→#4A /`, `#7C→#47 PrintScreen`); иначе
|
||||||
|
`L = XLAT_T[A]`.
|
||||||
|
|
||||||
|
### 3.5. ASCII-таблицы (`MODULE ASCII_TABLES`, строки 1285-1368)
|
||||||
|
Все таблицы ровно 90 байт (`Size EQU 90`):
|
||||||
|
- `ASCII_TABLES.ENGLISH` (1287-1295) — без шифта, англ
|
||||||
|
- `ASCII_TABLES.SHIFT_ENG` (1297-1305) — с шифтом, англ
|
||||||
|
- `ASCII_TABLES.CAPS_ENG` (1307-1315) — Caps, англ
|
||||||
|
- `ASCII_TABLES.CAPS_SHIFT_ENG` (1317-1325) — Caps+Shift, англ
|
||||||
|
- `ASCII_TABLES.RUSSIAN` (1328-1336) — без шифта, рус CP866
|
||||||
|
- `ASCII_TABLES.SHIFT_RUS` (1338-1346)
|
||||||
|
- `ASCII_TABLES.CAPS_RUS` (1348-1356)
|
||||||
|
- `ASCII_TABLES.CAPS_SHIFT_RUS` (1358-1366)
|
||||||
|
|
||||||
|
Старые метки `NORMTAB / SHIFTAB / CAPSTAB / SHF2TAB / NORMRUS / SHIFRUS
|
||||||
|
/ CAPSRUS / SHF2RUS` сохранились ТОЛЬКО в закомментированной legacy-копии
|
||||||
|
`K_SETUP` (строки 1097-1167) и **не являются живыми**. Все
|
||||||
|
KEYMAP/READMAP используют `ASCII_TABLES.*`.
|
||||||
|
|
||||||
|
### 3.6. K_SETUP подфункции (диспетчер на строке 934)
|
||||||
|
`INC B / DJNZ K_SND_R` — цепочка DJNZ:
|
||||||
|
| B | Метка | Поведение |
|
||||||
|
|---|-------|-----------|
|
||||||
|
| 0 | `KEYMAP` (937-972) / `READMAP` (974-1006) | Запись/чтение одной из 8 ASCII-таблиц. `HL=` буфер, `A bit7=0` запись, `bit7=1` чтение, биты0-2 = номер подтаблицы 0..7. Объём LDIR = `ASCII_TABLES.Size`=90 байт. Неверный A → `XOR A : SCF : RET` |
|
||||||
|
| 1 | `K_SND_R` (1019-1023) | `A := SOUND_K` |
|
||||||
|
| 2 | `K_SND_W` (1025-1030) | `SOUND_K := A` |
|
||||||
|
| 3 | `K_CURSOR_ON` (1034-1038) | Если `VMODE` показывает текстовый режим — `JP Cursor_On` |
|
||||||
|
| 4 | `K_CURSOR_OFF` (1042-1046) | То же → `JP Cursor_Off` |
|
||||||
|
| ≥5 | `K_SETUP.ERROR` (1015-1017) | `A = #0E INVALID_ACCESS, SCF, RET` |
|
||||||
|
|
||||||
|
### 3.7. Сканер клавиатуры — `KEYSCAN` (519-629)
|
||||||
|
- `LD IX,KEYFLAG` — IX указывает на блок состояния.
|
||||||
|
- **В текущем билде сканер ПОЛЛИНГ** (`KEYBOARD_INT_ENABLED=0`):
|
||||||
|
IF-блок строк 521-526 (который бы делал `CALL .RESCAN`, выход из INT)
|
||||||
|
НЕ ассемблируется. `KEYSCAN` падает прямо в `.RESCAN`. На практике он
|
||||||
|
вызывается из `INTx38_Handler` (`DSS-MAIN.ASM:275-306`), который сам
|
||||||
|
висит на `IM 1` `RST 38h`.
|
||||||
|
- **Логика `.RESCAN`** (от строки 527):
|
||||||
|
1. `IN A,(Z84.SIO.Ch_A.Ctrl)` — читаем RR0.
|
||||||
|
2. Если `bit0` (Rx Character Available) = 0 → `RET`.
|
||||||
|
3. Иначе пишем 1 в Ctrl (указать на регистр 1), читаем обратно,
|
||||||
|
тестируем `bit5` (Receiver Overrun) → ошибка → `JP KBD_Receiver_Overrun`
|
||||||
|
(1228) — дренаж FIFO, `OUT %00110000` в WR0 для error reset,
|
||||||
|
обнуление `KEYCTRL/KEY_FLG`.
|
||||||
|
4. Иначе `IN A,(Z84.SIO.Ch_A.Data)` (строка 538) — байт скан-кода.
|
||||||
|
5. Префиксы:
|
||||||
|
- `#F0` → `FULL_BF.F0_KEY`: устанавить `FLAG_F0`, `JP .RESCAN`.
|
||||||
|
- `#E0` → `FULL_BF.E0_KEY`: устанавить `FLAG_E0`, `JP .RESCAN`.
|
||||||
|
- `#E1` → если `USE_E1_SCANCODE=1` устанавить `FLAG_E1`,
|
||||||
|
иначе игнорировать.
|
||||||
|
6. Обычный байт + `FLAG_F0` → `UN_KEY` (657-664): `XLAT` → `UNSHIFT`
|
||||||
|
модификаторов, `UNCODE := HL` (последний отпущенный).
|
||||||
|
7. Обычный байт без `FLAG_F0` → `XLAT` → `SHIFTS` → сброс `FLAG_E0/E1` →
|
||||||
|
при `CHANGE_LANG_CTRL_SHIFT=1` опционально установить `CTRL_SHIFT` →
|
||||||
|
`INPCODE` → `PUTSYM` → `JP .RESCAN` (продолжать дренировать FIFO,
|
||||||
|
строка 628) — поскольку SIO имеет **3-байтовый Rx FIFO** (см. §6.4).
|
||||||
|
|
||||||
|
### 3.8. INPCODE/RUSCODE/CONVERT (875-930)
|
||||||
|
- **`INPCODE`** (875-906) — выбор одной из 4 английских таблиц на основе
|
||||||
|
`KEYCTRL` бит шифта и `KEYFLAG.CAPS_L`. Если `LANG_L` взведён → `JP RUSCODE`.
|
||||||
|
- **`RUSCODE`** (908-930) — то же для русских.
|
||||||
|
- **`CONVERT`** (901-906): `SET 7,D` (флаг keystroke), `HL = таблица+L`,
|
||||||
|
`E := (HL)`. После этого `PUTSYM`.
|
||||||
|
|
||||||
|
### 3.9. Курсор и звук
|
||||||
|
- **`Cursor`** (215-218) — переключатель: `CPL` `.Flag`, falls into
|
||||||
|
`Cursor_On`.
|
||||||
|
- **`Cursor_On`** (220-253): `BIOS.LP_GET_PLACE` (#8E) → DE=Y/X, сохранить;
|
||||||
|
`BIOS.WIN_GET_SYM` (#B4); вычислить глиф — `NORM_ZG=#1B` обычно,
|
||||||
|
`INS_CUR_ZG=#9B` при `INS_L`, `CURSOR_ZG=#5B` для фазы blink;
|
||||||
|
`BIOS.WIN_PUT_SYM.NoChangeZG` (`#01B5`); `LOCATE`.
|
||||||
|
- **`Cursor_Off`** (257-284): обратное действие; `JP LOCATE`.
|
||||||
|
- **`cursor_interrupt`** (287-295): тик. Если `.Flag != 0`, декрементировать
|
||||||
|
таймер; на нуле `CALL Cursor`.
|
||||||
|
- **`SETUP_CURSORS`** (298-375): один раз при старте подгружает кастомные
|
||||||
|
глифы (#5B блок и #9B инверт.) в страницу шрифта (`BANKTBL+TXTPAGE`)
|
||||||
|
через `BIOS.WIN_GET_ZG` (#B8) → CPL → `BIOS.WIN_SET_ZG` (#B6).
|
||||||
|
- **`BEEP`** (1173-1192): `DE=` период, `HL=` повторы. Тогглит A=#10/#00 в
|
||||||
|
`(SP_SND.Beeper)` = порт #FE бит 4.
|
||||||
|
|
||||||
|
### 3.10. Инициализация — `KEYBOARD_INIT` (1194-1224)
|
||||||
|
Последовательность для SIO Ch_A (стандартная Z80 SIO init):
|
||||||
|
- `DI`
|
||||||
|
- WR0 := 0 (clear pointer)
|
||||||
|
- WR4 := парам. (clock, stop, parity) — точные байты в коде, ср. с
|
||||||
|
`Another/SPRINTER/TASM/Keybdrv.z80` (там 9 байт init)
|
||||||
|
- WR3 := `#C1` (Rx enable, 8 бит/символ)
|
||||||
|
- WR5 := `#62` (`0110'0010`: бит3 **Tx Enable = 0 → передатчик ВЫКЛЮЧЕН**; биты5-6 = 8 бит/символ). Передача данных клавиатуре аппаратно отключена — см. §6.5
|
||||||
|
- WR1 := `%00011001` если `KEYBOARD_INT_ENABLED=1`, иначе 0
|
||||||
|
- `EI : RET`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Конвенция вызова DSS API
|
||||||
|
|
||||||
|
- **DSS**: `LD C,Dss.Xxx` (номер функции из `Shared_Includes/constants/dss_equ.inc`,
|
||||||
|
модуль `Dss:`), `RST 10` (= `ToDSS`). Параметры — в регистрах согласно
|
||||||
|
спецификации (см. [Shared_Includes/Docs/DSS_1.71_Functions.asm](Shared_Includes/Docs/DSS_1.71_Functions.asm),
|
||||||
|
раздел 6).
|
||||||
|
- **Выход**: `CF=0` — успех (значения в регистрах согласно функции);
|
||||||
|
`CF=1` — ошибка, `A=` код ошибки (`DSS_Error.sys.*`).
|
||||||
|
- **BIOS**: `LD C,BIOS.XXX` (`Shared_Includes/constants/BIOS_equ.inc`,
|
||||||
|
модуль `BIOS:`), `RST 08` (= `ToBIOS`). Перед вызовом необходим `DI` и
|
||||||
|
`OUT (#7C),0` для переключения банка BIOS; стек должен быть в `#8000-#BFFF`.
|
||||||
|
Подробно — [Shared_Includes/Docs/BIOS functions.asm](Shared_Includes/Docs/BIOS%20functions.asm), строки 1-60.
|
||||||
|
- **Подфункции**: верхний байт BC (т.е. `B`) — индекс подфункции; константа
|
||||||
|
обычно собрана как `EQU subfn*256 + .Func`. Пример: `Dss.K_SETUP.SetSoundVars
|
||||||
|
EQU 2*256+#36`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Compile-time флаги ([DSS/defines.inc](DSS/defines.inc))
|
||||||
|
|
||||||
|
| Флаг | Текущее | Что переключает в KEYINTER |
|
||||||
|
|------|---------|-----------------------------|
|
||||||
|
| `KEYBOARD_INT_ENABLED` (стр. 21) | `0` | `0` = поллинг из `INT 38h`; `1` = SIO Ch_A прерывание (WR1 := `#19`), отдельный обработчик в начале `KEYSCAN` |
|
||||||
|
| `CHANGE_LANG_CTRL_SHIFT` (стр. 22) | `1` | `1` = переключение языка Ctrl+Shift (через `CTRL_SHIFT` бит и `UNSHIFT.CHECK_CTRL_SHIFT`); `0` = Ctrl+Space (legacy путь `IFN CHANGE_LANG_CTRL_SHIFT` строки 585-591) |
|
||||||
|
| `BREAK_PROCESS_CODE` (стр. 23) | `#AC00` | Cooked-код Ctrl+C для `WaitKey`/`EDIT` → `DSS_Error.sys.USER_ABORT` (#25) |
|
||||||
|
| `USE_E1_SCANCODE` (стр. 24) | `0` | `1` = обрабатывать E1 (Pause/Break), `0` = игнорировать |
|
||||||
|
| `ENABLED_KEYBOARD_CONTROL` (стр. 24) | `0` | `1` = компилировать `FAKE_SHIFT` (игнор AT fake-shift `E0 12`/`E0 59` вокруг серых nav-клавиш). `0` = выключено: на железе SIO Tx отключён (WR5=`#62`), хост не может слать `0xED`, клавиатура не знает NumLock → fake-shift не приходит. Включать, только если появится двунаправленный канал к клавиатуре. См. §6.5 |
|
||||||
|
| `SHORT_RSTx10_TABLE` (стр. 10) | `0` | Должен быть `0` (либо ≥#37), иначе клавиатурные слоты не войдут в API table |
|
||||||
|
| `COMPILE_UNUSED_CODE` (стр. 11) | `0` | Гейтит legacy/debug куски |
|
||||||
|
|
||||||
|
Также в `defines.inc` — мышиные флаги (`MOUSE_INT_ENABLED`, ...) которые
|
||||||
|
делят с клавиатурой инфраструктуру SIO/IRQ.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Аппаратура Sprinter / Z84C15
|
||||||
|
|
||||||
|
### 6.1. Карта внутренних портов Z84C15
|
||||||
|
`Shared_Includes/constants/SP2000.inc`, `MODULE Z84` (строки 2111-2127):
|
||||||
|
|
||||||
|
| Порт | Назначение |
|
||||||
|
|------|------------|
|
||||||
|
| `#10..#13` | `CTC.Ch_0..3` (таймеры) |
|
||||||
|
| **`#18`** | `Z84.SIO.Ch_A.Data` — **PS/2 клавиатура DAT_A** |
|
||||||
|
| **`#19`** | `Z84.SIO.Ch_A.Ctrl` — **PS/2 клавиатура COM_A** |
|
||||||
|
| `#1A` | `SIO.Ch_B.Data` (DMOUSE) |
|
||||||
|
| `#1B` | `SIO.Ch_B.Ctrl` (CMOUSE) |
|
||||||
|
| `#1C..#1D` | `PIO.Port_A` — LPT1 (принтер) |
|
||||||
|
| `#1E..#1F` | `PIO.Port_B` — LPT2 |
|
||||||
|
| `#F0..#F1` | WDT |
|
||||||
|
| `#F4` | `IntPrior_Reg` |
|
||||||
|
| `#EE/#EF` | `SYS.Control / SYS.Data` |
|
||||||
|
|
||||||
|
Так что коммит `e334545 "M_INT: RFI is CH-A ONLY (per Z80 SIO spec)"`
|
||||||
|
относится к SIO Ch_A (клавиатура) — принтер на PIO, не на SIO.
|
||||||
|
|
||||||
|
### 6.2. Порт бипера и банкование
|
||||||
|
- `SP_SND.Beeper` = порт `#FE`, бит 4 (`%00010000`). Прямая запись из
|
||||||
|
KEYINTER (нет BIOS-функции для звука).
|
||||||
|
- `SLOT0..SLOT3` = `#82, #A2, #C2, #E2` — внешние порты переключения
|
||||||
|
страниц памяти на окна `#0000/#4000/#8000/#C000`. `SET_PAGE_X` из
|
||||||
|
`DSS_MACROSES.Z80` (137-143) использует SLOT3 + `BANKTBL[page]`.
|
||||||
|
- `TXTPAGE` — индекс в `BANKTBL` для страницы шрифта (используется в
|
||||||
|
`SETUP_CURSORS` строка 304). Если EQU не определён в снимке репо,
|
||||||
|
он приходит из внешнего SP2000-инклюда (см. `Build/Variables.inc`
|
||||||
|
после первой сборки).
|
||||||
|
|
||||||
|
### 6.3. Прерывания
|
||||||
|
- IM 1, единый вектор `#FF` для **кадрового И клавиатурного** прерывания.
|
||||||
|
- Различие: после входа в `INT 38h` ([DSS-MAIN.ASM:275](DSS/DSS-MAIN.ASM)),
|
||||||
|
читать порт `#19` (SIO Ch_A Ctrl/RR0); `bit0=1` → пришёл байт от
|
||||||
|
клавиатуры (в FIFO). Это и делает `KEYSCAN.RESCAN`.
|
||||||
|
- SIO Ch_A имеет **Rx FIFO на 3 байта** — `sp2000.pdf §9.4` явно
|
||||||
|
предписывает: «после обработки одного байта проверять, не пришло ли
|
||||||
|
ещё, и возвращаться только если FIFO пуст».
|
||||||
|
- Включение режима, при котором клавиатурный INT работает:
|
||||||
|
`Port_All_Mode` = `#204E`, биты `SPECTRUM_MODE_OFF=1` (бит 0) и
|
||||||
|
`STOP_KBD_INT_OFF=8` (бит 3) (см. `SP2000.inc`).
|
||||||
|
- Активный указатель ISR хранится в `SYS_PAGE.INT_ADRESS = #FEC124`,
|
||||||
|
`INT_PAGE = #FEC126`, `INT_ID = #FEC127` (сентинель `#AA` — установлено).
|
||||||
|
|
||||||
|
### 6.4. Z80 SIO регистры (для модификаций инициализации)
|
||||||
|
- **WR0** — command + pointer на следующий WR/RR.
|
||||||
|
- **WR1** — interrupt enable (бит 0 ExtINT, биты 1-2 Tx Int, биты 3-4 Rx Int
|
||||||
|
mode `%01100` = INT_ON_RXBYTE), бит 5 Wait/Ready.
|
||||||
|
- **WR2** — Interrupt vector (только Ch_B по Z80 SIO spec — нерелевантно
|
||||||
|
для клавиатуры).
|
||||||
|
- **WR3** — Rx control: bit0 Rx Enable, биты 6-7 Rx bits/character.
|
||||||
|
- **WR4** — clock multiplier, stop bits, parity.
|
||||||
|
- **WR5** — Tx control: бит 3 Tx Enable, биты 5-6 Tx bits/character.
|
||||||
|
- **RR0** — статус: **бит 0 = Rx Character Available** (то что тестирует
|
||||||
|
KEYINTER), бит 1 = Int Pending (CH-A only), бит 2 = Tx Buffer Empty,
|
||||||
|
бит 5 = Sync/Hunt, бит 6 = CTS, бит 7 = Break.
|
||||||
|
- **RR1** — special Rx conditions: framing/parity/overrun errors.
|
||||||
|
- Полный datasheet — Zilog Z80 SIO Technical Manual (UM008); в репо его
|
||||||
|
нет, см. ссылки в §8.
|
||||||
|
|
||||||
|
### 6.5. Команды PS/2 хост→клавиатура (host commands)
|
||||||
|
Если потребуется управлять светодиодами Caps/Num/Scroll или autorepeat,
|
||||||
|
то протокол описан в [/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Keyboard/KBD.TXT](/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Keyboard/KBD.TXT):
|
||||||
|
- `#FF` reset+self-test, `#FE` resend, `#F4` enable scanning, `#F5` disable+default,
|
||||||
|
- `#ED` set LEDs (bit0 Scroll, bit1 Num, bit2 Caps),
|
||||||
|
- `#F3` set typematic rate+delay (биты 6-5 delay 250/500/750/1000 ms,
|
||||||
|
биты 4-0 rate 6..30 cps),
|
||||||
|
- `#F2` read keyboard ID,
|
||||||
|
- `#FB-#FD`, `#F7-#FA` per-key/all-keys typematic.
|
||||||
|
|
||||||
|
**Передача клавиатуре аппаратно невозможна в текущей конфигурации**: `KEYBOARD_INIT`
|
||||||
|
ставит WR5 = `#62` (бит3 Tx Enable = 0), т.е. передатчик SIO Ch_A выключен.
|
||||||
|
Поэтому host-команды (`0xED` Set LEDs, autorepeat и др.) не отправляются и не могут.
|
||||||
|
|
||||||
|
Важное следствие про **fake-shift**: по стандарту AT/PS-2 клавиатура шлёт fake-shift
|
||||||
|
(`E0 12` / `E0 59` вокруг серых extended nav-клавиш — стрелки/Ins/Del/Home/End/PgUp/PgDn)
|
||||||
|
ТОЛЬКО когда её внутренний Num Lock-LED включён. А LED выставляет ТОЛЬКО хост командой
|
||||||
|
`0xED` (нажатие Num Lock для клавиатуры — обычный скан-код `0x77`, своё состояние она не
|
||||||
|
меняет). Раз `0xED` послать нельзя → клавиатура всегда считает Num Lock выключенным →
|
||||||
|
**fake-shift на реальном железе не генерируется**, выделенные стрелки всегда приходят
|
||||||
|
чисто (`E0 6B` и т.п.). Обработка fake-shift реализована в `FAKE_SHIFT`, но компилируется
|
||||||
|
только при `ENABLED_KEYBOARD_CONTROL=1` (§5) — на железе это мёртвый код, нужен лишь для
|
||||||
|
эмуляторов (MAME msnat сам моделирует Num Lock+fake-shift, чего на железе быть не может).
|
||||||
|
Чтобы реально слать команды — включить Tx (WR5 бит3=1) и писать в `#18` после проверки
|
||||||
|
готовности Tx Buffer (RR0 bit2).
|
||||||
|
|
||||||
|
### 6.6. CMOS-привязка
|
||||||
|
- `CMOS_CELL.BootUpParams` = `#0E`, `.Mask.Language = %0000'0100` — пресет
|
||||||
|
языка при загрузке.
|
||||||
|
- `CMOS_CELL.Typematic` = `#0F`, маски `.Enabled %1000'0000`,
|
||||||
|
`.Delay %0110'0000`, `.Rate %0000'0111`.
|
||||||
|
- Доступ через `BIOS.CMOS_RD (#F6) / CMOS_WR (#F7)` или прямые порты
|
||||||
|
`CMOS.Port.{Data.Read=#FFBD, Data.Write=#BFBD, Address.Write=#DFBD}`.
|
||||||
|
- **Сейчас KEYINTER НЕ читает CMOS** — состояние локов и языка
|
||||||
|
сбрасывается на каждый boot к дефолтам. Если нужна persistence,
|
||||||
|
добавлять в `KEYBOARD_INIT` или в высокоуровневый `AUTOEXEC.BAT`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Reference материалы
|
||||||
|
|
||||||
|
### 7.1. В репозитории
|
||||||
|
| Документ | Что искать |
|
||||||
|
|----------|------------|
|
||||||
|
| [Shared_Includes/Docs/sp2000.pdf](Shared_Includes/Docs/sp2000.pdf) | §1.1 Sp2000 hardware (p.4), §1.3 block diagram (p.5), §9 Внутренние порты Z84C15 (p.21), **§9.4 AT-Клавиатура p.25-26** (COM_A/DAT_A, sample code), §13.2 карта портов p.31 |
|
||||||
|
| [Shared_Includes/Docs/BIOS functions.asm](Shared_Includes/Docs/BIOS%20functions.asm) | Раздел 5 «Функции печати и управления режимом экрана» (стр. 628-1100): `LP_PRINT_SYM #82`, `LP_PRINT_ALL #81`, `LP_SET_PLACE #84`, `LP_GET_PLACE #8E`, `WIN_GET_SYM #B4`, `WIN_PUT_SYM #B5`, `WIN_GET_ZG #B8`, `WIN_SET_ZG #B6`, `LP_SCROLL_UD #8A`, `LP_PR_LINE_DIR #E0`. Конвенция вызова — стр. 1-60 |
|
||||||
|
| [Shared_Includes/Docs/DSS_1.71_Functions.asm](Shared_Includes/Docs/DSS_1.71_Functions.asm) | **Раздел 6 «Функции ввода с клавиатуры» (строки ~364-446)** — авторитетная спецификация на функции #30..#37 с корректировками из последней сессии (Pause Lock bit6, CTRLKey A=#FF/A=0, K_CLEAR INVALID_FUNCTION, K_SETUP B=0 это Get/Set table transfer) |
|
||||||
|
| [Shared_Includes/constants/dss_equ.inc](Shared_Includes/constants/dss_equ.inc) | `Dss.WaitKey..TestKey` (137-149), `Dss.K_SETUP.*` (144-148), `DSS_Error.sys.*` (280-336), **Приложение А — позиционные коды клавиш** (547-595) |
|
||||||
|
| [Shared_Includes/constants/BIOS_equ.inc](Shared_Includes/constants/BIOS_equ.inc) | `BIOS.*` функции (см. §7.1 ниже) |
|
||||||
|
| [Shared_Includes/constants/SP2000.inc](Shared_Includes/constants/SP2000.inc) | `MODULE Z84` (2111-2127), `SP_SND`, `ACEX.*`, `ZXKeys.Line_*` (#FEFE..#7FFE legacy ZX), `Port_All_Mode #204E`, `SYS_PAGE.INT_*`, `CMOS_CELL.*` |
|
||||||
|
| [Shared_Includes/constants/zx_char_codes.inc](Shared_Includes/constants/zx_char_codes.inc) | Control codes ZX: `.cursor_left=#08 (backspace)`, `.right=#09 (== TAB!)`, `.cursor_down=#0A`, `.cursor_up=#0B`, `.delete_left=#0C`, `.carriage_return=#0D`, и т.п. |
|
||||||
|
| [Shared_Includes/constants/dss_errors.z80](Shared_Includes/constants/dss_errors.z80) | Строки ошибок: #01 Invalid function, #0E Unknown operation, #13 Access denied, #20 Operation not supported, #25 User abort, #27 Unexpected app termination |
|
||||||
|
| [DSS/DSS_MAP.TXT](DSS/DSS_MAP.TXT) | Карта памяти ядра — #0400-#043F SBUF, #0440-#0BD1 KEYBOARD DRIVER |
|
||||||
|
| [DSS/CHANGES.LOG](DSS/CHANGES.LOG) | Хронология; ECHOKEY cursor 2003-02-10, txt 40x32 cursor bug, OVR cursor square |
|
||||||
|
| [DSS/KNOWN.BUG](DSS/KNOWN.BUG) | §3.3-3.4 — legacy ECHOKEY/PUTCHAR закомментированы, можно убирать; буферы #100/#80 без bounds-check |
|
||||||
|
|
||||||
|
### 7.2. В `Another/` (референсы, не собираются)
|
||||||
|
| Файл | Зачем |
|
||||||
|
|------|-------|
|
||||||
|
| [/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Sprinter_Programming.pdf](/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Sprinter_Programming.pdf) | **p.22 «Прерывания»** (вектор #FF, бит 0 порта #19), **p.25-26 «Клавиатура»** (пример K_SETUP layout-table, 9×16=144 байта на подтаблицу, Ctrl+Space layout switch), p.27 коды ошибок |
|
||||||
|
| [/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Keyboard/KBD.TXT](/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Keyboard/KBD.TXT) | PS/2 host→keyboard команды (см. §6.5) |
|
||||||
|
| [/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Keyboard/AT-Keyboard.pdf](/Users/tolik/Documents/SP_Projects/ASM/Another/Docs/Keyboard/AT-Keyboard.pdf) | Scan Code Set 2 на 3 страницах |
|
||||||
|
| [/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/TASM/Keybdrv.z80](/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/TASM/Keybdrv.z80) | Минималистский standalone-драйвер клавиатуры Дениса Паринова (517 строк): полная init-последовательность 9 байт WR0..WR5 на ComA=#19, чтение DataA=#18. Полезно при отладке железа отдельно от DSS |
|
||||||
|
| [/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/TASM/Scantabl.z80](/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/TASM/Scantabl.z80), [Scantabl2.z80](/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/TASM/Scantabl2.z80) | Альтернативные scancode→symbol таблицы (для сверки `XLAT_T`) |
|
||||||
|
| [/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/SRC/cpm3-s/SCAN.PLM](/Users/tolik/Documents/SP_Projects/ASM/Another/SPRINTER/SRC/cpm3-s/SCAN.PLM) | CP/M-3 Sprinter scan-логика на PL/M (третий независимый референс) |
|
||||||
|
| **НЕ нужно**: `Another/scancode.inc` | NASM/x86 BIOS INT16h (Sergey Kiselev Micro-8088). Другая архитектура, пропустить |
|
||||||
|
|
||||||
|
### 7.3. Внешние (нужно скачать)
|
||||||
|
- **Zilog Z80 SIO Technical Manual (UM008)** — главы 3-4: полный layout
|
||||||
|
`WR0..WR7` / `RR0..RR2`. `sp2000.pdf §9` явно отсылает туда («Ссылка
|
||||||
|
на описание PIO, SIO и т.д. от Zilog»).
|
||||||
|
- **Zilog Z84C15 Product Specification** — карта внутренних портов,
|
||||||
|
CTC/PIO timing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. История изменений KEYINTER (git log)
|
||||||
|
|
||||||
|
`git log --oneline -- DSS/KEYINTER.ASM`:
|
||||||
|
- **9235af1** RUS keys fix
|
||||||
|
- **f5eacf4** KEYINTER.ASM: russian chars fix
|
||||||
|
- **e334545** M_INT: RFI is CH-A ONLY (per Z80 SIO spec) — **сохранять**
|
||||||
|
CH-A-only RFI семантику при правках ISR
|
||||||
|
- **73c7ab5** K_SETUP show/hide cursor sub-fns
|
||||||
|
- **12c0287** ECHOKEY scroll fix
|
||||||
|
- **eae2582** PutChar via BIOS LP_PR_LINE_DIR (#E0)
|
||||||
|
- **23fa77a** XLAT_T overflow + Ctrl+C
|
||||||
|
- **ff2f2b9** layout-switch combo (Ctrl+Space vs Shift+Ctrl) compile flag
|
||||||
|
- **54b1e80** SIO experiments
|
||||||
|
|
||||||
|
При работе всегда смотреть `git log -p DSS/KEYINTER.ASM | head -200` —
|
||||||
|
часто старые комментарии R-номерами (R01, R02 ...) поясняют исторические
|
||||||
|
правки.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Полезные команды на хост-системе
|
||||||
|
|
||||||
|
- **Сборка ядра**: VS Code task `Build SYSTEM.DOS` (или `[NEW]` с
|
||||||
|
инкрементом билда). Из терминала примерно:
|
||||||
|
```
|
||||||
|
cd "/Users/tolik/Documents/SP_Projects/ASM/GIT/Estex DSS"
|
||||||
|
sjasmplus --syntax=afw --fullpath -Wno-shortblock \
|
||||||
|
--lst=Build/DSS-MAIN.LST --raw=Build/DSS/SYSTEM.DOS \
|
||||||
|
--exp=Build/Variables.inc DSS/DSS-MAIN.ASM
|
||||||
|
```
|
||||||
|
- **Деплой в MAME**: VS Code task `Copy all files to MAME` → запускает
|
||||||
|
[RUN/Image.sh](RUN/Image.sh) (zsh, `hdfmonkey`).
|
||||||
|
- **Запуск MAME**: VS Code task `Run MAME`.
|
||||||
|
- **Прочитать CP866-файл с правильной кодировкой**:
|
||||||
|
```
|
||||||
|
iconv -f CP866 -t UTF-8 DSS/KEYINTER.ASM | less
|
||||||
|
```
|
||||||
|
- **grep по бинарно-определяемым файлам** (CP866 ломает heuristic):
|
||||||
|
```
|
||||||
|
grep -anE "WAITKEY|KEYSCAN" DSS/KEYINTER.ASM
|
||||||
|
```
|
||||||
|
Флаг `-a` форсит text-режим.
|
||||||
|
- **Просмотр с табами**:
|
||||||
|
```
|
||||||
|
sed -n '519,540p' DSS/KEYINTER.ASM | tr -d '\r' | cat -tv
|
||||||
|
```
|
||||||
|
- **Дамп диспетч-таблицы**:
|
||||||
|
```
|
||||||
|
sed -n '337,396p' DSS/DSS-MAIN.ASM
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Стилевые соглашения
|
||||||
|
|
||||||
|
- Кодировка CP866 (DOS Russian), переводы строк CRLF. Edit'ы должны их
|
||||||
|
сохранять.
|
||||||
|
- Отступы — табы. Комментарии справа от инструкции выровнены табами до
|
||||||
|
колонки `;`. При вставке новых комментариев-продолжений использовать
|
||||||
|
4 таба + `;`.
|
||||||
|
- Рамки секций — `;████...████` (символ █ = U+2588). Не ломать.
|
||||||
|
- Стиль меток: метки целиком капсом (`KEYSCAN`, `WAITKEY`), вложенные
|
||||||
|
через `.` (`KEYSCAN.RESCAN`, `K_SETUP.ERROR`, `Cursor_Off.Flag`).
|
||||||
|
- Self-modifying code маркирован комментариями вроде `;R01`, `;R13` с
|
||||||
|
ревизионными номерами — НЕ удалять без причины (это история).
|
||||||
|
- Хроноразметка `[ ] DD/MM/YYYY` / `[x]` для done — в комментариях.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10а. Работа с файлами CP866 + CRLF (практические рецепты)
|
||||||
|
|
||||||
|
Это **главный источник тонких багов** при редактировании. Прочитай эту
|
||||||
|
секцию ДО первой правки.
|
||||||
|
|
||||||
|
### 10а.1. Что именно в CP866
|
||||||
|
- Все `DSS/*.asm`, `DSS/*.ASM`, `DSS/*.inc`, `DSS/*.Z80`.
|
||||||
|
- Все `Shared_Includes/constants/*.inc` и `Shared_Includes/Docs/*.asm`.
|
||||||
|
- `DSS/CHANGES.LOG`, `DSS/KNOWN.BUG`, `DSS/DSS_MAP.TXT`.
|
||||||
|
- `Another/SPRINTER/...`, `Another/Docs/Keyboard/KBD.TXT`.
|
||||||
|
|
||||||
|
PDF в `Shared_Includes/Docs/sp2000.pdf` и `Another/Docs/*.pdf` — отдельная
|
||||||
|
история (текст внутри PDF в своей кодировке, см. `pdftotext`).
|
||||||
|
|
||||||
|
UTF-8 в этом проекте бывает только в `*.md` (вроде этого файла), `*.json`
|
||||||
|
(VSCode-конфиги), `*.sh`, `*.lua` и `.gitmodules`.
|
||||||
|
|
||||||
|
### 10а.2. Байтовая карта CP866 (минимум, который надо помнить)
|
||||||
|
| Байт(ы) | Что |
|
||||||
|
|---------|-----|
|
||||||
|
| `#80..#8F` | `А..О` (рус. заглавные, первая половина) |
|
||||||
|
| `#90..#9F` | `П..Я` (рус. заглавные, вторая половина) |
|
||||||
|
| `#A0..#AF` | `а..п` (рус. строчные, первая половина) |
|
||||||
|
| `#B0..#B2` | `░ ▒ ▓` (shading) |
|
||||||
|
| `#B3..#DA` | псевдографика `│ ─ ┌ ┐ ┘ └ ┤ ├ ┬ ┴ ┼ …` и двойные `║ ═` |
|
||||||
|
| **`#DB`** | **`█` — full block, из которого строятся рамки `;██..██` в этом проекте** |
|
||||||
|
| `#DC..#DF` | `▄ ▌ ▐ ▀` |
|
||||||
|
| `#E0..#EF` | `р..я` (рус. строчные, вторая половина) |
|
||||||
|
| `#F0, #F1` | `Ё ё` |
|
||||||
|
| `#FC` | `№` |
|
||||||
|
| `#FE` | `■` |
|
||||||
|
|
||||||
|
Важно:
|
||||||
|
- **`█` = один байт `#DB` в CP866**, а в UTF-8 это **три байта `E2 96 88`**.
|
||||||
|
Поэтому строчка `;████████` длиной ~110 символов в CP866 занимает ~110
|
||||||
|
байт, а в UTF-8 — ~330 байт.
|
||||||
|
- Если случайно конвертнуть файл в UTF-8 и забыть конвертнуть обратно,
|
||||||
|
размер файла резко вырастает, выравнивание комментариев плывёт, а
|
||||||
|
sjasmplus может выдать странные ошибки на строковых литералах.
|
||||||
|
|
||||||
|
### 10а.3. Просмотр и поиск
|
||||||
|
|
||||||
|
**Просмотр через тулзу Read**: русский текст может отображаться как
|
||||||
|
заполнители или мусор, потому что Read декодирует как UTF-8. Полагаться
|
||||||
|
на это для содержания комментариев **нельзя** — но для проверки кода
|
||||||
|
(меток, инструкций Z80, hex-литералов) подходит.
|
||||||
|
|
||||||
|
**Просмотр в человеческой форме** — через Bash + iconv:
|
||||||
|
```sh
|
||||||
|
iconv -f CP866 -t UTF-8 DSS/KEYINTER.ASM | less
|
||||||
|
iconv -f CP866 -t UTF-8 DSS/KEYINTER.ASM | sed -n '519,540p'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Просмотр с табами/CRLF**:
|
||||||
|
```sh
|
||||||
|
sed -n '519,540p' DSS/KEYINTER.ASM | iconv -f CP866 -t UTF-8 | cat -tev
|
||||||
|
# ^I = табы, $ = конец строки (CRLF будет показан как ^M$)
|
||||||
|
```
|
||||||
|
|
||||||
|
**grep по ASCII-меткам** — `-a` обязательно:
|
||||||
|
```sh
|
||||||
|
grep -an "WAITKEY\|KEYSCAN\|K_SETUP" DSS/KEYINTER.ASM
|
||||||
|
```
|
||||||
|
Без `-a` grep с какого-то порога считает CP866 бинарным и молча выдаёт
|
||||||
|
только имя файла.
|
||||||
|
|
||||||
|
**grep по русским словам** — через pipe iconv (номера строк сохраняются,
|
||||||
|
т.к. количество переводов строк не меняется):
|
||||||
|
```sh
|
||||||
|
iconv -f CP866 -t UTF-8 DSS/KEYINTER.ASM | grep -an "клавиш"
|
||||||
|
```
|
||||||
|
Альтернатива: сконвертить запрос в CP866 и грепать байтами (но это
|
||||||
|
крайне неудобно — pipe-метод лучше).
|
||||||
|
|
||||||
|
**Полный hex-дамп строки** (для разбора, что именно лежит в файле):
|
||||||
|
```sh
|
||||||
|
sed -n '519p' DSS/KEYINTER.ASM | xxd | head
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10а.4. Редактирование — критическое
|
||||||
|
|
||||||
|
**Главная проблема Edit-инструмента**: он работает на байтовом уровне.
|
||||||
|
Если файл в CP866, а `old_string` в твоей tool-call'е содержит русский
|
||||||
|
текст в UTF-8, то байты НЕ совпадут и Edit упадёт с `String not found`.
|
||||||
|
Если случайно `new_string` запишется UTF-8'ом в CP866-файл, файл
|
||||||
|
ломается локально (на конкретной строке).
|
||||||
|
|
||||||
|
**Безопасные паттерны**:
|
||||||
|
1. **ASCII-only анкоры (90% случаев)**. Выбирай `old_string` так, чтобы он
|
||||||
|
состоял из инструкций Z80, меток, hex-литералов и английских/латинских
|
||||||
|
фрагментов. Кириллический хвост строки пройдёт «как есть» — Edit не
|
||||||
|
трогает то, что не в old_string.
|
||||||
|
```
|
||||||
|
old_string: " RST ToDSS\t\t\t; "
|
||||||
|
```
|
||||||
|
Это сработает, даже если справа после `; ` идёт русский комментарий.
|
||||||
|
|
||||||
|
2. **Если кириллица обязана быть в old_string** (например, надо заменить
|
||||||
|
текст внутри русского комментария) — сначала **сконвертировать
|
||||||
|
фрагмент в CP866** через Bash:
|
||||||
|
```sh
|
||||||
|
echo -n "максимальный номер диска" | iconv -f UTF-8 -t CP866 | xxd
|
||||||
|
```
|
||||||
|
получишь байты, и можешь искать/заменять через `sed` или `perl` с
|
||||||
|
`LC_ALL=C` (байтовый режим), а не через Edit.
|
||||||
|
|
||||||
|
3. **Удобный трюк**: убедиться, что `old_string` уникально совпадает с
|
||||||
|
ASCII-частью комментария или ID:
|
||||||
|
```
|
||||||
|
old_string: " LD A,disk_num\t\t\t; "
|
||||||
|
new_string: " LD H,device_num\t\t; "
|
||||||
|
```
|
||||||
|
и оставить хвостовую кириллицу в покое.
|
||||||
|
|
||||||
|
4. **Не вставляй русский текст напрямую через Edit**, если файл в CP866.
|
||||||
|
Если требуется добавить русский комментарий, сделай это через Bash:
|
||||||
|
```sh
|
||||||
|
echo -n "; новый комментарий" | iconv -f UTF-8 -t CP866 >> /tmp/append
|
||||||
|
# затем вставляй байты через sed/perl
|
||||||
|
```
|
||||||
|
Или согласись писать новые комментарии на английском/латинице (ASCII)
|
||||||
|
— это безопаснее, и стиль файла это терпит.
|
||||||
|
|
||||||
|
### 10а.5. Сохранение CRLF
|
||||||
|
- Файлы используют `\r\n` (Windows-стиль), не `\n`.
|
||||||
|
- При вставке новых строк через Edit убедись, что в `new_string` есть
|
||||||
|
`\r` перед `\n`. Если Edit-инструмент это съест и поставит только
|
||||||
|
`\n`, файл получит **смешанные line endings** — sjasmplus съест, но
|
||||||
|
`git diff` будет показывать всю окрестность как изменённую, и в
|
||||||
|
Windows-редакторах текст рассыпется.
|
||||||
|
- **Альтернатива**: после Edit-сессии нормализуй переводы строк:
|
||||||
|
```sh
|
||||||
|
# Проверить:
|
||||||
|
file DSS/KEYINTER.ASM
|
||||||
|
# Должно быть: "with CRLF line terminators"
|
||||||
|
# Если стало "with CRLF, LF line terminators" — есть смесь, чинить:
|
||||||
|
perl -i -pe 's/\r?\n/\r\n/g' DSS/KEYINTER.ASM
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10а.6. Проверка после правки (обязательная)
|
||||||
|
```sh
|
||||||
|
file DSS/KEYINTER.ASM
|
||||||
|
# Ожидается: "Non-ISO extended-ASCII text, with CRLF line terminators"
|
||||||
|
# НЕ должно быть "UTF-8 Unicode text" или "with LF line terminators"
|
||||||
|
|
||||||
|
# Проверка, что рамки █ не превратились в UTF-8 (3 байта):
|
||||||
|
grep -c $'\xDB\xDB\xDB' DSS/KEYINTER.ASM
|
||||||
|
# Должно быть положительное число (несколько штук). 0 = рамки сломаны.
|
||||||
|
|
||||||
|
# git diff с пониманием бинарного представления:
|
||||||
|
git diff DSS/KEYINTER.ASM | cat -v | head -50
|
||||||
|
# Cyrillic должен показываться как M-X M-X последовательности байт
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10а.7. Откат, если что-то сломалось
|
||||||
|
```sh
|
||||||
|
# Один файл — мгновенный откат:
|
||||||
|
git checkout HEAD -- DSS/KEYINTER.ASM
|
||||||
|
|
||||||
|
# Если уже закоммитил битый файл — посмотреть предыдущую версию:
|
||||||
|
git show HEAD~1:DSS/KEYINTER.ASM | iconv -f CP866 -t UTF-8 | less
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10а.8. Конвертация всего файла «туда-обратно» (последнее средство)
|
||||||
|
Если правок очень много и проще править в UTF-8:
|
||||||
|
```sh
|
||||||
|
# 1. Конвертация в UTF-8 + переход на LF (так удобнее редактировать):
|
||||||
|
iconv -f CP866 -t UTF-8 DSS/KEYINTER.ASM | tr -d '\r' > /tmp/KEYINTER.utf8
|
||||||
|
|
||||||
|
# 2. Правки в /tmp/KEYINTER.utf8 любым инструментом (Edit/sed/perl).
|
||||||
|
|
||||||
|
# 3. Обратно в CP866 + восстановление CRLF:
|
||||||
|
iconv -f UTF-8 -t CP866 /tmp/KEYINTER.utf8 | perl -pe 's/\r?\n/\r\n/g' > DSS/KEYINTER.ASM
|
||||||
|
|
||||||
|
# 4. Проверка:
|
||||||
|
file DSS/KEYINTER.ASM
|
||||||
|
git diff --stat DSS/KEYINTER.ASM
|
||||||
|
```
|
||||||
|
**Риск**: если в файле есть байты, не имеющие пары CP866↔UTF-8 (теоретически
|
||||||
|
вряд ли в этом проекте, но возможно при кривых правках в истории), iconv
|
||||||
|
ругнётся с `illegal input sequence`. Тогда `iconv -c` пропустит проблемные
|
||||||
|
байты — но они **потеряются**. Безопаснее в этом случае работать
|
||||||
|
ASCII-only анкорами через Edit.
|
||||||
|
|
||||||
|
### 10а.9. VS Code как замена тулинга
|
||||||
|
Если хочется визуальной правки:
|
||||||
|
- VS Code: правый-нижний угол → `Reopen with Encoding → Cyrillic (CP866)`.
|
||||||
|
- Для постоянной ассоциации `.asm/.ASM/.inc` с CP866 добавить в
|
||||||
|
`.vscode/settings.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"[asm]": { "files.encoding": "cp866" },
|
||||||
|
"files.eol": "\r\n"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- При сохранении проверь нижнюю панель — индикатор должен показывать
|
||||||
|
«CP866» и «CRLF», а не «UTF-8» / «LF».
|
||||||
|
|
||||||
|
### 10а.10. Чек-лист: «изменения сохранят кодировку»
|
||||||
|
- [ ] `file <изменённый.asm>` → `Non-ISO extended-ASCII text, with CRLF line terminators`
|
||||||
|
- [ ] `grep -c $'\xDB\xDB\xDB' <изменённый.asm>` > 0 (если в файле были рамки)
|
||||||
|
- [ ] `git diff <изменённый.asm> | wc -l` разумного размера (не в 3× больше ожидаемого — иначе UTF-8 раздувание)
|
||||||
|
- [ ] Сборка `Build SYSTEM.DOS` проходит без warning'ов вроде «invalid character in string literal»
|
||||||
|
- [ ] Открыть результат в VS Code с CP866 — комментарии читаются по-русски
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Что важно помнить, прежде чем менять KEYINTER
|
||||||
|
|
||||||
|
1. **Файл подключается `INCLUDE`'ом** в `DSS-MAIN.ASM:402`, сборка идёт
|
||||||
|
как монолит. Все символы видны глобально.
|
||||||
|
2. **Состояние клавиатуры — RAM-only**: не персистится в CMOS. Любая
|
||||||
|
настройка (язык, локи, sound flags, ASCII-таблицы) теряется на
|
||||||
|
reset/power-off, если её не сохранить через AUTOEXEC.BAT.
|
||||||
|
3. **Клавиатура и мышь делят окно INT 38h** — мышь идёт после `KEYSCAN`.
|
||||||
|
Долгая работа в `KEYSCAN` задерживает мышь.
|
||||||
|
4. **SIO Ch_A FIFO = 3 байта** — `.RESCAN` должен дренировать его
|
||||||
|
полностью за один заход (текущая реализация это делает через
|
||||||
|
`JP .RESCAN` на строке 628).
|
||||||
|
5. **`KEYBOARD_INT_ENABLED=0`** — текущий билд поллит, не использует SIO
|
||||||
|
INT. Если хочется перейти на прерывания, нужно переключить флаг,
|
||||||
|
убедиться что `KEYBOARD_INIT` пишет WR1=`#19`, и проверить что
|
||||||
|
обработчик RFI в `DSS-MAIN.ASM` корректно настроен (Z80 SIO Ch_A only).
|
||||||
|
6. **При правке HEAD/HOST убедиться, что `RES 6,(HL)` сохранён** — это
|
||||||
|
обеспечивает wrap modulo 64. Если изменишь размер `SBUF`, поменяй и
|
||||||
|
маску (бит-логика `RES 6` работает только для 64 = #40).
|
||||||
|
7. **При правке `XLAT_T`** — длина 144 байта (`Size`), bounds-check
|
||||||
|
`CP XLAT_T.Size` на строке 860. Если расширяешь, проверь, что не
|
||||||
|
натыкаешься на следующую область (`CURRENT DIR NAME BUFFER` по
|
||||||
|
DSS_MAP.TXT идёт от #1343).
|
||||||
|
8. **Двойственность `D` в записях буфера**: D[7] = «keystroke flag»,
|
||||||
|
D[6:0] = позиционный код 0..#5A. `INPCODE/CONVERT` ставит бит 7 через
|
||||||
|
`SET 7,D` — это видимый паттерн.
|
||||||
|
9. **При правке ASCII-таблиц** — каждая ровно 90 байт, проверяется
|
||||||
|
`ASSERT .Size = Size`. Если меняешь размер, меняй и `Size EQU 90`
|
||||||
|
на строке 1286.
|
||||||
|
10. **Звук работает в обход BIOS** — прямой `OUT (SP_SND.Beeper),A`
|
||||||
|
(порт #FE бит 4). Это запрещает звуковые эффекты, если процесс
|
||||||
|
держит порт #FE для других целей (ZX-режим). Учитывать при
|
||||||
|
модификациях `BEEP`/`FULL_BF`/`LANG_X`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Чек-лист первого подхода
|
||||||
|
|
||||||
|
Сначала открой и прочитай (именно в таком порядке):
|
||||||
|
1. [DSS/KEYINTER.ASM](DSS/KEYINTER.ASM) целиком (1371 строка).
|
||||||
|
2. [DSS/DSS-MAIN.ASM](DSS/DSS-MAIN.ASM): строки 187-213 (`RST_10`),
|
||||||
|
275-310 (`INTx38_Handler`), 337-396 (`DSS_API_TABLE`), 402 (INCLUDE),
|
||||||
|
423 (`BANKTBL`), 567-600 (boot-флоу).
|
||||||
|
3. [DSS/defines.inc](DSS/defines.inc) (короткий).
|
||||||
|
4. [Shared_Includes/Docs/DSS_1.71_Functions.asm](Shared_Includes/Docs/DSS_1.71_Functions.asm), раздел 6.
|
||||||
|
5. [Shared_Includes/constants/dss_equ.inc](Shared_Includes/constants/dss_equ.inc), приложение А (позиционные коды).
|
||||||
|
6. `Another/Docs/Sprinter_Programming.pdf` p.22, p.25-26 (страницы 25-26 содержат
|
||||||
|
пример K_SETUP layout-table).
|
||||||
|
7. `sp2000.pdf` §9.4 (PDF, страница ~25-26).
|
||||||
|
8. Скачать Zilog Z80 SIO Technical Manual (UM008), если будешь трогать
|
||||||
|
`KEYBOARD_INIT` или `KBD_Receiver_Overrun`.
|
||||||
|
|
||||||
|
Только после этого формулируй гипотезу и план правок.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Контрольные вопросы перед коммитом
|
||||||
|
|
||||||
|
- [ ] Тестовая сборка `Build SYSTEM.DOS` прошла без ошибок?
|
||||||
|
- [ ] Кодировка файлов сохранена CP866/CRLF? (`file DSS/KEYINTER.ASM`
|
||||||
|
должен показать `Non-ISO extended-ASCII text, with CRLF line terminators`)
|
||||||
|
- [ ] Табы и выравнивание комментариев не нарушены?
|
||||||
|
- [ ] Если изменён публичный API (#30..#37) — обновлён ли
|
||||||
|
[Shared_Includes/Docs/DSS_1.71_Functions.asm](Shared_Includes/Docs/DSS_1.71_Functions.asm)?
|
||||||
|
- [ ] Если изменены константы (`Dss.K_SETUP.*`, ASCII-таблица size,
|
||||||
|
коды ошибок) — обновлён ли `dss_equ.inc`?
|
||||||
|
- [ ] Если изменена инициализация SIO — проверено, что коммит совместим
|
||||||
|
с `e334545 "RFI is CH-A ONLY"`?
|
||||||
|
- [ ] MAME-прогон (`Run MAME` / `Copy all files to MAME`): клавиатура
|
||||||
|
реагирует, переключение языка работает, INS/CAPS/NUM/SCRL ведут себя
|
||||||
|
ожидаемо?
|
||||||
|
- [ ] Echo (`ECHOKEY`) рисует курсор корректно во всех текстовых режимах
|
||||||
|
(40×32, 80×32)?
|
||||||
|
- [ ] `XLAT_T` не вылез за `Size=144`?
|
||||||
|
|
||||||
|
Удачи.
|
||||||
Loading…
Reference in New Issue
Block a user