;[BEGIN] ;//MODULE: INTMOUSE ;//CREATE: 19-05-1998 AUTHOR: Denis Parinov ;//UPDATE: 24-10-1999 DNS Restore module PORT_MOUSE.Ctrl EQU Z84.SIO.Ch_B.Ctrl PORT_MOUSE.Data EQU Z84.SIO.Ch_B.Data ; MOUSE SOFTWARE SPECIFICATION ;--------------------------------------------- ; COMMAND 00h (INITIALIZATION) ; ; RETURN: NC - MOUSE PRESENT ; C - MOUSE ABSENT ;--------------------------------------------- ; COMMAND 01h (SHOW MOUSE CURSOR) ; ; RETURN: NC - DONE ; C - MOUSE ON SCREEN ;--------------------------------------------- ; COMMAND 02h (HIDE MOUSE CURSOR) ; ; RETURN: NC - DONE ; C - NONE MOUSE ;--------------------------------------------- ; COMMAND 03h (READ MOUSE STATE) ; ; RETURN: HL - X COORD ; DE - Y COORD ; A - BUTTONS D2-D0 (MIDDLE,RIGHT,LEFT) ;--------------------------------------------- ; COMMAND 04h (GOTO MOUSE CURSOR) ; ; INPUT: HL - X COORD ; DE - Y COORD ;--------------------------------------------- ; COMMAND 05h (RESERVED) ;--------------------------------------------- ; COMMAND 06h (RESERVED) ;--------------------------------------------- ; COMMAND 07h (SET VERT. BOUNDS) ; ; INPUT: HL - Y MIN ; DE - Y MAX ;--------------------------------------------- ; COMMAND 08h (SET HORZ. BOUNDS) ; ; INPUT: HL - X MIN ; DE - X MAX ;--------------------------------------------- ; COMMAND 09h (LOAD CURSOR) ; ; INPUT: IX - CURSOR IMAGE ; H - HEIGHT CURSOR ; L - WIDTH CURSOR ; D - Y HOT SPOT ; E - X HOT SPOT ; B = 0 ;--------------------------------------------- ; COMMAND 0Ah (SET CURSOR IN TEXT MODES) ; ; INPUT: H - AND SIMBOL MASK ; L - XOR SIMBOL MASK ; D - AND ATTRIBUT MASK ; E - XOR ATTRIBUT MASK ; B = 0 ;--------------------------------------------- ; COMMAND 0Bh (RETURN CURSOR) ; ; INPUT: IX - CURSOR IMAGE BUFFER ; OUTPUT: H - HEIGHT CURSOR ; L - WIDTH CURSOR ; D - Y HOT SPOT ; E - X HOT SPOT ;--------------------------------------------- ; COMMAND 0Ch (RESERVED) ;--------------------------------------------- ; COMMAND 0Dh (RESERVED) ;--------------------------------------------- ; COMMAND 0Eh (GET SENSITIVE) ; OUTPUT: H - VERTICAL SENSITIVE ; L - HORIZONTAL SENSITIVE ;--------------------------------------------- ; COMMAND 0Fh (SET SENSITIVE) ; INPUT: H - VERTICAL SENSITIVE ; L - HORIZONTAL SENSITIVE ;--------------------------------------------- ; COMMAND 80h (MOUSE HARDWARE INTERRUPT) ;--------------------------------------------- ; COMMAND 81h (CHANGE VIDEO MODE) ; INPUT: A - MODE ;--------------------------------------------- ; COMMAND 82h (RESERVED) ;--------------------------------------------- ; COMMAND 83h (MOUSE REFRESH) ;--------------------------------------------- ; ERRORS: 0 - NO ERROR ; 1 - COMMAND NOT PRESENT ; 2 - DEVICE ABSENT ; 3 - CURSOR ON (UZHE) ; 4 - CURSOR OFF (UZHE) ; 5 - CURSOR IMAGE VERY BIG INTMOUS: BIT 7,C JR NZ,EMOUSE INC C DEC C JR Z,MS_INIT ; 0 DEC C JR Z,MS_SHOW ; 1 DEC C JP Z,MS_HIDD ; 2 DEC C JP Z,MS_READ ; 3 DEC C JP Z,MS_GOTO ; 4 DEC C JR Z,.RESERVED ; 5 DEC C JR Z,.RESERVED ; 6 DEC C JP Z,MS_VERT ; 7 DEC C JP Z,MS_HORZ ; 8 DEC C JP Z,MS_CURS ; 9 DEC C JP Z,MS_MASK ; 10 DEC C JP Z,MS_BCUR ; 11 DEC C JR Z,.RESERVED ; 12 DEC C JR Z,.RESERVED ; 13 DEC C JP Z,MS_GSEN ; 14 DEC C JP Z,MS_SENT ; 15 .RESERVED: LD A,DSS_Error.mouse.INVALID_COMMAND SCF RET EMOUSE: RES 7,C INC C DEC C JP Z,M_INT DEC C JP Z,M_MODE DEC C JR Z,.RESERVED DEC C JP Z,M_REFR .RESERVED: LD A,DSS_Error.mouse.INVALID_COMMAND SCF RET ;!TODO на биос. MS_INIT: DI ; reg 0 XOR A OUT (PORT_MOUSE.Ctrl),A ; reg 4 - скорость порта первый множитель LD A,4 OUT (PORT_MOUSE.Ctrl),A ;LD A,+(5 | MOUSE_BAUD.multiplier_1) ; parity LD A,+(4 | MOUSE_BAUD.multiplier_1) ; no parity OUT (PORT_MOUSE.Ctrl),A ; reg 3 LD A,3 OUT (PORT_MOUSE.Ctrl),A LD A,#41 ;LD A,#C1 OUT (PORT_MOUSE.Ctrl),A ; reg 5 LD A,5 OUT (PORT_MOUSE.Ctrl),A LD A,%1110'0000 ; bit7 для корректного инита Sega джойстика в порту кемпстон джойстика OUT (PORT_MOUSE.Ctrl),A IF MOUSE_INT_ENABLED ; reg 1 LD A,1 OUT (PORT_MOUSE.Ctrl),A LD A,%0001'1001 OUT (PORT_MOUSE.Ctrl),A ; reg 2 LD A,2 OUT (PORT_MOUSE.Ctrl),A LD A,#FF ; вектор прерывания #FF OUT (PORT_MOUSE.Ctrl),A ELSE ; reg 1 LD A,1 OUT (PORT_MOUSE.Ctrl),A XOR A OUT (PORT_MOUSE.Ctrl),A ENDIF ; скорость порта - второй множитель LD A,#55 OUT (Z84.CTC.Ch_0),A LD A,MOUSE_BAUD.multiplier_2 OUT (Z84.CTC.Ch_0),A ; EI XOR A RET MS_SHOW: PUSH IX PUSH HL PUSH DE EX AF,AF' PUSH AF LD HL,(PIX_X) LD DE,(PIX_Y) DI CALL MOUSE XOR A LD (REFRESH.hide),A EI POP AF EX AF,AF' POP DE POP HL POP IX XOR A RET MS_HIDD: PUSH IX PUSH HL PUSH DE EX AF,AF' PUSH AF DI LD A,1 LD (REFRESH.hide),A CALL RESTORE EI POP AF EX AF,AF' POP DE POP HL POP IX XOR A RET MS_READ: LD HL,(PIX_X) LD DE,(PIX_Y) LD A,(MOUSE_BUTTONS) AND A RET MS_GOTO: PUSH IX PUSH HL PUSH DE LD (PIX_X),HL LD (PIX_Y),DE EX AF,AF' PUSH AF DI CALL REFRESH EI POP AF EX AF,AF' POP DE POP HL POP IX XOR A RET MS_CURS: PUSH BC PUSH DE PUSH HL PUSH IX LD A,L LD (M_XSIZE),A LD A,H LD (M_YSIZE),A LD C,E LD B,0 LD (XHOT_SP),BC LD C,D LD B,0 LD (YHOT_SP),BC EXX LD A,(M_XSIZE) LD C,A LD B,0 LD A,(M_YSIZE) LD HL,0 .loop: ADD HL,BC DEC A JR NZ,.loop PUSH HL LD BC,M_IMAGE.Size+1 AND A SBC HL,BC CCF EXX POP BC POP HL LD A,5 JR C,.NOLOADM LD DE,M_IMAGE DI LDIR XOR A .NOLOADM: POP HL POP DE POP BC EI RET MS_BCUR: PUSH IX EXX LD A,(M_XSIZE) LD C,A LD B,0 LD A,(M_YSIZE) LD HL,0 .loop: ADD HL,BC DEC A JR NZ,.loop PUSH HL LD BC,M_IMAGE.Size+1 AND A SBC HL,BC CCF EXX POP BC POP HL LD A,5 JR C,NOSAVEM LD DE,M_IMAGE EX DE,HL DI LDIR LD A,(M_XSIZE) LD L,A LD A,(M_YSIZE) LD H,A LD BC,(XHOT_SP) LD E,C LD BC,(YHOT_SP) LD D,C LD BC,0 XOR A NOSAVEM: EI RET MS_HORZ: LD (MIN_X),HL LD (MAX_X),DE XOR A RET MS_VERT: LD (MIN_Y),HL LD (MAX_Y),DE XOR A RET MS_MASK: LD (ANDXORS),HL LD (ANDXORA),DE XOR A RET ; H - VERTICAL SENSITIVE ; L - HORIZONTAL SENSITIVE MS_SENT: LD (SENSEXY),HL XOR A RET MS_GSEN: LD HL,(SENSEXY) XOR A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; RESTORE: .sw+1: LD A,#00 BIT 7,A JP Z,.TXT ; restore gfx-mode IN A,(SLOT3) LD B,A IN A,(PORT_Y) LD C,A PUSH BC LD A,#50 ;!HARDCODE videopage OUT (SLOT3),A .X+1: LD HL,0 .Y+1: LD DE,0 LD A,E EX AF,AF' .SCR+1: LD A,0 AND 1 LD DE,SLOT3.MEM_ADDR ;screen 0 JR Z,.adr LD DE,SLOT3.MEM_ADDR+320 ;screen 1 .adr: ADD HL,DE .YSize+1: LD A,0 LD XH,A EX AF,AF' .loop: ; .Xsize+1: LD BC,10 OUT (PORT_Y),A EX AF,AF' LD (.PUSH_HL),HL LD D,H LD E,L LDIR .PUSH_HL+1: LD HL,#0000 EX AF,AF' INC A JR Z,.no_dec DEC XH JR NZ,.loop .no_dec: POP BC LD A,B OUT (SLOT3),A LD A,C OUT (PORT_Y),A XOR A RET .TXT: ; restore txt-mode .TXT_X+1: LD HL,#0000 .TXT_Y+1: LD DE,#0000 ; IN A,(PORT_Y) LD XH,A IN A,(SLOT3) LD XL,A ; LD A,#50 ; CALL GET_SYMBOL_ADDR ; LD (HL),A INC L LD A,(HL) ;ATTRIBUT ;JR SET_RESTORE_EXIT ;---------------------------------------------------------------; SET_RESTORE_EXIT: LD (HL),A ; LD A,XL OUT (SLOT3),A LD A,XH OUT (PORT_Y),A RET ;---------------------------------------------------------------; GET_SYMBOL_ADDR:;Y SRL D RR E SRL D RR E SRL D RR E LD D,E ;X SRL H RR L SRL H RR L SRL H RR L LD E,L ; DI OUT (SLOT3),A ; LD A,D ADD A,A ADD A,A ;Y * 4 LD L,A LD H,high (SLOT3.MEM_ADDR + #300) ;#300 - описатели экрана ; IN A,(SCREEN_SWITCH) RRCA AND #80 OR #01 ADD A,E OUT (PORT_Y),A INC L LD A,(HL) ;SIMBOL ; RET ;---------------------------------------------------------------; ;----------------------------------------------------------------------; ;HL/DE - X/Y MOUSE: LD A,(MODE_M) LD (RESTORE.sw),A BIT 7,A JP NZ,.GFX ; ; set txt-mode .TXT: LD (RESTORE.TXT_X),HL LD (RESTORE.TXT_Y),DE ; IN A,(PORT_Y) LD XH,A IN A,(SLOT3) LD XL,A ; LD A,#54 ; CALL GET_SYMBOL_ADDR ; LD BC,(ANDXORS) AND B XOR C LD (HL),A INC L LD A,(HL) ;ATTRIBUT LD BC,(ANDXORA) AND B XOR C JR SET_RESTORE_EXIT ; ;set gfx-mode .GFX: CP Dss.SetVMod.grf640x256 JR NZ,.NOFIX_640 SRL H RR L .NOFIX_640: LD IX,M_IMAGE LD A,(M_XSIZE) LD C,A LD B,0 LD (REALXS),BC LD (RESTORE.Xsize),BC LD C,B LD (SKIPXF),BC LD A,(M_YSIZE) LD (RESTORE.YSize),A LD C,A LD B,0 LD (REALYS),BC LD BC,(YHOT_SP) LD A,E SUB C LD E,A JR NC,.GOOD_Y NEG LD E,A LD A,(M_XSIZE) LD C,A LD B,0 LD A,(M_YSIZE) SUB E .SKIPMY: ADD IX,BC DEC E JR NZ,.SKIPMY LD C,A LD (REALYS),BC .GOOD_Y: LD BC,(XHOT_SP) AND A SBC HL,BC JR NC,.GOOD_X LD B,H LD C,L LD HL,0 AND A SBC HL,BC LD (SKIPXF),HL LD A,(M_XSIZE) SUB L LD L,A LD (REALXS),HL LD HL,0 .GOOD_X: LD (RESTORE.X),HL LD (RESTORE.Y),DE ; PUSH HL IN A,(SLOT3) LD H,A IN A,(PORT_Y) LD L,A EX (SP),HL LD A,#5C ;!HARDCODE videopage OUT (SLOT3),A LD A,E EX AF,AF' IN A,(SCREEN_SWITCH) LD (RESTORE.SCR),A AND 1 LD DE,SLOT3.MEM_ADDR ;Screen 0 JR Z,.adr LD DE,SLOT3.MEM_ADDR+320 ;Screen 1 .adr: ADD HL,DE LD D,XH LD E,XL EX DE,HL ;HL - BITMAP LD BC,(REALYS) LD XH,C EX AF,AF' ; .loop: LD BC,(SKIPXF) ADD HL,BC LD BC,(REALXS) OUT (PORT_Y),A EX AF,AF' LD (.PUSH_DE),DE LDIR .PUSH_DE+1: LD DE,#0000 EX AF,AF' INC A JR Z,.exit_loop DEC XH JR NZ,.loop ; .exit_loop: POP BC LD A,B OUT (SLOT3),A LD A,C OUT (PORT_Y),A XOR A RET ;----------------------------------------------------------------------; CLEAR_MOUSE_BUFFER: IN A,(Z84.SIO.Ch_B.Data) IN A,(Z84.SIO.Ch_B.Ctrl) RRCA JR C,CLEAR_MOUSE_BUFFER SCF RET ;----------------------------------------------------------------------; READ_M: ;[ ] 18/02/2024 проверка на переполнение буфера ; reg 1 LD A,1 OUT (PORT_MOUSE.Ctrl),A IN A,(PORT_MOUSE.Ctrl) AND %0010'0000 ; check receiver overrun error ; JP NZ,.Receiver_Overrun JR Z,.READ_FIRST_BYTE ; reg 0 - error reset LD A,%0011'0000 OUT (Z84.SIO.Ch_B.Ctrl),A JP CLEAR_MOUSE_BUFFER .READ_FIRST_BYTE: IN A,(PORT_MOUSE.Ctrl) RRCA RET NC ; AND 1 ; RET Z IN A,(PORT_MOUSE.Data) LD L,A AND %0100'0000 ;BIT 6,A ;CCF RET Z ;[x] mouse freeeeezzzz ;LD BC,MOUSE_READ_PORT_TIMEOUT ; .READ_SECOND_BYTE: IN A,(PORT_MOUSE.Ctrl) RRCA ;[x] mouse freeeeezzzz ;JR C,.NXT_1 ;DEC BC ;LD A,B ;OR C ;JR NZ,.TST_01 ;RET JR NC,.READ_SECOND_BYTE ; ;.NXT_1: IN A,(PORT_MOUSE.Data) LD E,A AND %0100'0000 ;CCF RET NZ ;[x] mouse freeeeezzzz ;LD BC,MOUSE_READ_PORT_TIMEOUT ; .READ_LAST_BYTE: IN A,(PORT_MOUSE.Ctrl) RRCA ;[x] mouse freeeeezzzz ;JR C,.NXT_2 ;DEC BC ;LD A,B ;OR C ;JR NZ,.READ_LAST_BYTE ;RET JR NC,.READ_LAST_BYTE ; ;.NXT_2: IN A,(PORT_MOUSE.Data) LD D,A ;BIT 6,A AND %0100'0000 ;CCF RET NZ ; все три байта пакета прочитаны ; LD A,E AND #3F LD E,A LD A,L AND #03 RRCA RRCA OR E LD E,A LD A,D AND #3F LD D,A LD A,L AND #0C RRCA RRCA RRCA RRCA OR D LD D,A LD A,L RLCA RLCA RLCA RES 6,A JR NC,.STBU SET 6,A .STBU: RLCA RLCA AND #03 LD (MOUSE_BUTTONS),A CALL SENSE LD (MOUSE_COORDINATES),DE ; LD A,E ; LD (MX),A ; LD A,D ; LD (MY),A SCF RET ;[ ] 14/03/2024 проверка на переполнение буфера /* .Receiver_Overrun: ; empty the buffer IN A,(Z84.SIO.Ch_B.Data) IN A,(Z84.SIO.Ch_B.Ctrl) RRCA JR C,.Receiver_Overrun ; reg 0 - error reset LD A,%0011'0000 OUT (Z84.SIO.Ch_B.Ctrl),A ;!TEST ; reg 0 - return from int ; LD A,%0011'1000 ; OUT (Z84.SIO.Ch_B.Ctrl),A ; RET */ MCORECT: LD HL,(PIX_X) LD DE,(MOUSE_COORDINATES) LD D,0 BIT 7,E JR NZ,.DECX ADD HL,DE LD (PIX_X),HL EX DE,HL LD HL,(MAX_X) AND A SBC HL,DE JR NC,.YCOO LD HL,(MAX_X) LD (PIX_X),HL JP .YCOO .DECX: LD A,E NEG LD E,A AND A SBC HL,DE LD (PIX_X),HL JR C,.YCOO2 LD DE,(MIN_X) SBC HL,DE JR NC,.YCOO .YCOO2: LD HL,(MIN_X) LD (PIX_X),HL .YCOO: LD HL,(PIX_Y) LD DE,(MOUSE_COORDINATES.Y) LD D,0 BIT 7,E JR NZ,DECY ADD HL,DE LD (PIX_Y),HL EX DE,HL LD HL,(MAX_Y) AND A SBC HL,DE RET NC LD HL,(MAX_Y) LD (PIX_Y),HL RET DECY: LD A,E NEG LD E,A AND A SBC HL,DE LD (PIX_Y),HL JR C,.XCOO LD DE,(MIN_Y) SBC HL,DE RET NC .XCOO: LD HL,(MIN_Y) LD (PIX_Y),HL RET SENSE: LD HL,(SENSEXY) LD A,L ; [ ] 15/03/2024 теперь поправки чувствительности по координатам работают корректно ;OR L ;RET Z ;DEC A ;RET Z CP 2 CCF JR NC,.check_Y ; LD A,E BIT 7,A LD B,#FF JR Z,.loop LD B,#7F NEG .loop: INC B SUB L JR NC,.loop BIT 7,B JR Z,.next LD A,B RES 7,A NEG LD B,A ; .next: LD E,B ; [ ] 15/03/2024 теперь поправки чувствительности по координатам работают корректно .check_Y: LD A,H CP 2 CCF RET NC ; LD A,D BIT 7,A LD B,#FF JR Z,.loop2 LD B,#7F NEG .loop2: INC B SUB H JR NC,.loop2 BIT 7,B JR Z,.skip2 LD A,B RES 7,A NEG LD B,A .skip2: LD D,B RET M_MODE: LD (MODE_M),A OR A JR Z,.UNKMODE CP 1 JR Z,.UNKMODE CP 2 JR Z,S320256 CP 3 JR Z,S640256 BIT 7,A JR Z,.UNKMODE RES 7,A CP 1 JR Z,S320256 CP 2 JR Z,S640256 .UNKMODE: XOR A ; ????? может тут надо .INVALID_COMMAND ? SCF RET S320256: LD HL,0 ;MIN X LD DE,319 ;MAX X CALL MS_HORZ LD HL,0 ;MIN X LD DE,255 ;MAX X CALL MS_VERT XOR A RET S640256: LD HL,0 ;MIN X LD DE,639 ;MAX X CALL MS_HORZ LD HL,0 ;MIN X LD DE,255 ;MAX X CALL MS_VERT XOR A RET ;Mouse Interrupt M_INT: IN A,(SLOT3) LD B,A IN A,(PORT_Y) LD C,A PUSH BC CALL REFRESH ;Refresh mouse CALL CONTROL POP BC LD A,B OUT (SLOT3),A LD A,C OUT (PORT_Y),A ;!TEST SIO INT IF MOUSE_INT_ENABLED LD A,%0011'1000 ; return from int OUT (Z84.SIO.Ch_B.Ctrl),A ENDIF RET M_REFR: CALL CONTROL AND A RET CONTROL: CALL READ_M RET NC CALL MCORECT ;LD A,#00 ; XOR A ; LD (REDY),A RET REFRESH: .hide+1: LD A,#01 OR A RET NZ ; ; REDY+1: LD A,#01 ; OR A ; RET NZ ; CALL RESTORE LD HL,(PIX_X) LD DE,(PIX_Y) CALL MOUSE ; LD A,#FF ; LD (REDY),A RET MODE_M: DB #03 PIX_X: DW 160 PIX_Y: DW 128 MOUSE_COORDINATES: .X: DB #00 .Y: DB #00 MOUSE_BUTTONS: DB #00 ;MB_OLD DB #00 ; !FIXIT - не нужно? MIN_X: DW 0 MAX_X: DW 319 MIN_Y: DW 0 MAX_Y: DW 255 SENSEXY: ; Сэн Сэкси .X: DB 0 .Y: DB 2 XHOT_SP: DW 0 YHOT_SP: DW 0 ANDXORS: DW #FF00 ANDXORA: DW #FF77 M_XSIZE: DB 10 M_YSIZE: DB 14 SKIPXF: DW 0 REALXS: DW 0 REALYS: DW 0 ; Xx EQU #00 ; Ww EQU #FE ; Nn EQU #FF ;MS_BMP M_IMAGE: DH "00 00 FF FF FF FF FF FF FF FF" DH "00 FE 00 FF FF FF FF FF FF FF" DH "00 FE FE 00 FF FF FF FF FF FF" DH "00 FE FE FE 00 FF FF FF FF FF" DH "00 FE FE FE FE 00 FF FF FF FF" DH "00 FE FE FE FE FE 00 FF FF FF" DH "00 FE FE FE FE FE FE 00 FF FF" DH "00 FE FE FE FE 00 00 00 00 FF" DH "00 FE FE 00 FE 00 FF FF FF FF" DH "00 FE 00 00 FE FE 00 FF FF FF" DH "00 00 FF FF 00 FE 00 FF FF FF" DH "00 FF FF FF 00 FE FE 00 FF FF" DH "FF FF FF FF FF 00 00 FF FF FF" DH "FF FF FF FF FF FF FF FF FF FF" BLOCK 256-($-M_IMAGE),0 .Size EQU $-M_IMAGE ;//MODULE: INTMOUSE ;[END]