mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
294 changed files with 16433 additions and 10259 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,567 @@ |
|||
; 24.9.2018 PMS (b1ackmai1er) |
|||
; Modified version for ECB-ZILOG PERIPHERALS BOARD - TEST 2 PIO's |
|||
; 01.11.2011 WKA |
|||
; Assembler M80 |
|||
; ECB-4PIO |
|||
; Testprogramm f�r die I/O-Karte ECB-4PIO in Z80-Mnemonics |
|||
|
|||
PAGE 72 |
|||
.Z80 |
|||
ASEG |
|||
ORG 100H |
|||
; |
|||
;CP/M-ADDRESSES |
|||
;* * * * * * * |
|||
; |
|||
BOOT EQU 0 ;WARMBOOT CP/M |
|||
BDOS EQU 5 ;ENTRY BDOS |
|||
NMI EQU 66H ;Error-ROUTINE |
|||
; |
|||
;CONSOLE-CODES |
|||
;* * * * * * * |
|||
; |
|||
EOT EQU 4 ;END OF TEXT |
|||
BS EQU 8 ;BACKSPACE |
|||
TAB EQU 9 ;TABULATOR |
|||
LF EQU 0AH ;LINE-FEED |
|||
CR EQU 0DH ;CARRIAGE-RETURN |
|||
FF EQU 0CH ;FORM-FEED |
|||
ESC EQU 1BH ;ESCAPE |
|||
CTRLC EQU 'C'-40H ;CONTROL-C |
|||
CTRLW EQU 'W'-40H ;CONTROL-W |
|||
CTRLX EQU 'X'-40H ;CONTROL-X |
|||
CTRLY EQU 'Y'-40H ;CONTROL-Y |
|||
CTRLZ EQU 'Z'-40H ;CONTROL-Z |
|||
; |
|||
BASE EQU 0B8H ; 4 DIL-SCHALTER |
|||
; |
|||
PIO0AD EQU BASE+0 ; PIO 0 A DATEN |
|||
PIO0AC EQU BASE+2 ; PIO 0 A CONTROL |
|||
PIO0BD EQU BASE+1 ; PIO 0 B DATEN |
|||
PIO0BC EQU BASE+3 ; PIO 0 B CONTROL |
|||
; |
|||
PIO1AD EQU BASE+4 ; PIO 1 A DATEN |
|||
PIO1AC EQU BASE+6 ; PIO 1 A CONTROL |
|||
PIO1BD EQU BASE+5 ; PIO 1 B DATEN |
|||
PIO1BC EQU BASE+7 ; PIO 1 B CONTROL |
|||
; |
|||
MAIN: LD DE,PIO_SRTMSG |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,INI_MSG |
|||
CALL PSTRIN |
|||
CALL INIT |
|||
; |
|||
LD DE,PIO0ADW ;PIO0 A |
|||
CALL PSTRIN |
|||
LD A,55H |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO0AD),A |
|||
IN A,(PIO0AD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO0ADR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO0ADW |
|||
CALL PSTRIN |
|||
LD A,0AAH |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO0AD),A |
|||
IN A,(PIO0AD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO0ADR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO0BDW ;PIO0 B |
|||
CALL PSTRIN |
|||
LD A,55H |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO0BD),A |
|||
IN A,(PIO0BD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO0BDR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO0BDW |
|||
CALL PSTRIN |
|||
LD A,0AAH |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO0BD),A |
|||
IN A,(PIO0BD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO0BDR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO1ADW ;PIO1 A |
|||
CALL PSTRIN |
|||
LD A,55H |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO1AD),A |
|||
IN A,(PIO1AD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO1ADR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO1ADW |
|||
CALL PSTRIN |
|||
LD A,0AAH |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO1AD),A |
|||
IN A,(PIO1AD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO1ADR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO1BDW ;PIO1 B |
|||
CALL PSTRIN |
|||
LD A,55H |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO1BD),A |
|||
IN A,(PIO1BD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO1BDR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO1BDW |
|||
CALL PSTRIN |
|||
LD A,0AAH |
|||
PUSH AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
POP AF |
|||
OUT (PIO1BD),A |
|||
IN A,(PIO1BD) |
|||
PUSH AF |
|||
; |
|||
LD DE,PIO1BDR |
|||
CALL PSTRIN |
|||
POP AF |
|||
CALL OUTB |
|||
LD DE,LINE_E |
|||
CALL PSTRIN |
|||
; |
|||
LD DE,PIO_ENDMSG |
|||
CALL PSTRIN |
|||
JP BOOT |
|||
; |
|||
;========================================================================== |
|||
INIT: LD HL,PIO0T ; PIO0 INITITALISIEREN |
|||
CALL INITX |
|||
LD HL,PIO1T ; PIO1 INITITALISIEREN |
|||
CALL INITX |
|||
RET |
|||
; |
|||
INITX: LD A,(HL) ; BYTE-ANZAHL |
|||
OR A |
|||
RET Z |
|||
LD B,A ; Port-Adresse nach C |
|||
INC HL |
|||
LD C,(HL) |
|||
INC HL |
|||
OTIR |
|||
JR INITX |
|||
; |
|||
PIO0T: DEFB 05 ; 5 BYTE ZUM PIO 0 A CONTROL |
|||
DEFB PIO0AC |
|||
DEFB 00000011B ; DIS-INT |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 11001111B ; BETR.ART BIT EIN/AUSG. |
|||
DEFB 00000000B ; ALLES AUSG. |
|||
DEFB 01 ; 1 BYTE ZUM PIO 0 A DATEN |
|||
DEFB PIO0AD |
|||
DEFB 00000000B ; DATEN "LOW" |
|||
; |
|||
DEFB 05 ; 5 BYTE ZUM PIO 0 B CONTROL |
|||
DEFB PIO0BC |
|||
DEFB 00000011B ; DIS-INT |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 11001111B ; BETR.ART BIT EIN/AUSG. |
|||
DEFB 00000000B ; ALLES AUSG. |
|||
DEFB 01 ; 1 BYTE ZUM PIO 0 B DATEN |
|||
DEFB PIO0BD |
|||
DEFB 00000000B ; DATEN "LOW" |
|||
DEFB 0 ; ENDE PIO 0 B -TABELLE |
|||
; |
|||
PIO1T: DEFB 05 ; 5 BYTE ZUM PIO 1 A CONTROL |
|||
DEFB PIO1AC |
|||
DEFB 00000011B ; DIS-INT |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 11001111B ; BETR.ART BIT EIN/AUSG. |
|||
DEFB 00000000B ; ALLES AUSG. |
|||
DEFB 01 ; 1 BYTE ZUM PIO 1 A DATEN |
|||
DEFB PIO1AD |
|||
DEFB 00000000B ; DATEN "LOW" |
|||
; |
|||
DEFB 05 ; 5 BYTE ZUM PIO 1 B CONTROL |
|||
DEFB PIO1BC |
|||
DEFB 00000011B ; DIS-INT |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 01001111B ; BETR.ART BYTE EINGABE |
|||
DEFB 11001111B ; BETR.ART BIT EIN/AUSG. |
|||
DEFB 00000000B ; ALLES AUSG. |
|||
DEFB 01 ; 1 BYTE ZUM PIO 1 B DATEN |
|||
DEFB PIO1BD |
|||
DEFB 00000000B ; DATEN "LOW" |
|||
DEFB 0 ; ENDE PIO 1 B -TABELLE |
|||
; |
|||
;========================================================================== |
|||
; |
|||
;Output on Screen |
|||
;**************** |
|||
; |
|||
PRBS: LD E,BS |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Output CR+LF on Screen |
|||
;********************** |
|||
; |
|||
CRLF: LD E,CR |
|||
CALL PCHAR |
|||
LD E,LF |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Output ASCII-Character |
|||
;********************** |
|||
; |
|||
PRINP: PUSH AF |
|||
LD E,A |
|||
CALL PCHAR |
|||
POP AF |
|||
RET; |
|||
; |
|||
;CALL BDOS with Register Save |
|||
;**************************** |
|||
; |
|||
INCHA: LD C,1 ;INPUT CHARACTER TO A |
|||
JR BDO |
|||
PCHAR: LD C,2 ;PRINT CHARACTER IN E |
|||
JR BDO |
|||
PSTRIN: LD C,9 ;PRINT STRING |
|||
JR BDO |
|||
INBUFF: LD C,10 ;READ CONSOLE-BUFFER |
|||
JR BDO |
|||
CSTS: LD C,11 ;CONSOLE-STATUS |
|||
JR BDO |
|||
OPEN: LD C,15 ;OPEN FILE |
|||
JR BDO |
|||
CLOSE: LD C,16 ;CLOSE FILE |
|||
JR BDO |
|||
DELETE: LD C,19 ;DELETE FILE |
|||
JR BDO |
|||
READS: LD C,20 ;READ SEEK |
|||
JR BDO |
|||
WRITES: LD C,21 ;WRITE SEEK |
|||
JR BDO |
|||
MAKE: LD C,22 ;MAKE FILE |
|||
JR BDO |
|||
SETDMA: LD C,26 ;SET DMA-ADDRESS |
|||
BDO: PUSH HL |
|||
PUSH DE |
|||
PUSH BC |
|||
PUSH IX |
|||
PUSH IY |
|||
CALL BDOS |
|||
POP IY |
|||
POP IX |
|||
POP BC |
|||
POP DE |
|||
POP HL |
|||
RET |
|||
; |
|||
;DIRECT CONSOLE INPUT |
|||
;******************** |
|||
; |
|||
INDCON: CALL INDCOX |
|||
CP 0 |
|||
JR Z,INDCON |
|||
RET |
|||
; |
|||
INDCOX: LD C,6 ;Code for Direct Console Input |
|||
LD E,0FFH ;Code for Input |
|||
PUSH HL |
|||
PUSH DE |
|||
PUSH BC |
|||
PUSH IX |
|||
PUSH IY |
|||
CALL BDOS |
|||
POP IY |
|||
POP IX |
|||
POP BC |
|||
POP DE |
|||
POP HL |
|||
RET |
|||
; |
|||
; |
|||
;Output WORD |
|||
;*********** |
|||
; |
|||
;PARAMETER: Entry WORD IN HL |
|||
;********* |
|||
; |
|||
OUTW: LD A,H |
|||
CALL OUTB |
|||
LD A,L |
|||
CALL OUTB |
|||
RET |
|||
; |
|||
;Output BYTE |
|||
;*********** |
|||
; |
|||
;PARAMETER: Entry BYTE IN A |
|||
;********* |
|||
; |
|||
OUTB: PUSH AF |
|||
RRCA |
|||
RRCA |
|||
RRCA |
|||
RRCA |
|||
AND 0FH |
|||
CALL HBTHE ;Change Half-BYTE |
|||
POP AF |
|||
AND 0FH |
|||
CALL HBTHE |
|||
RET |
|||
; |
|||
;Output HALF-BYTE |
|||
;**************** |
|||
; |
|||
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3) |
|||
;********* |
|||
; |
|||
HBTHE: CP 0AH |
|||
JR C,HBTHE1 |
|||
ADD A,7 ;Character to Letter |
|||
HBTHE1: ADD A,30H |
|||
LD E,A |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Input ADDRESS |
|||
;************* |
|||
; |
|||
;PARAMETER: Exit with ADDRESS IN HL |
|||
;********* |
|||
; |
|||
INADR: LD HL,0 |
|||
INADR1: CALL INCHAR ;Input TETRADE |
|||
LD D,A |
|||
CALL INBYT1 ;IN HEXA |
|||
RET C ;END OF Input |
|||
ADD HL,HL |
|||
ADD HL,HL |
|||
ADD HL,HL |
|||
ADD HL,HL |
|||
OR L |
|||
LD L,A |
|||
JR INADR1 ;New Key |
|||
; |
|||
; |
|||
;Input BYTE |
|||
;********** |
|||
; |
|||
;PARAMTER: Exit with BYTE IN A |
|||
;******** |
|||
; |
|||
INBYT: CALL INADR |
|||
LD A,L |
|||
RET |
|||
; |
|||
;Input of one TETRADE to A (BIT 0-3) |
|||
;************************************ |
|||
; |
|||
INBYT1: SUB '0' |
|||
RET C |
|||
CP 'G'-30H |
|||
JR NC,INBYT3 ;Error |
|||
CP ':'-30H |
|||
JR C,INBYT2 |
|||
CP 'A'-30H |
|||
JR C,INBYT3 ;Error |
|||
SUB 7 |
|||
INBYT2: OR A |
|||
RET |
|||
; |
|||
INBYT3: SCF |
|||
RET |
|||
; |
|||
;Input ASCII-Character to A |
|||
;************************** |
|||
; |
|||
INCON: CALL INDCON ;Input ASCII-Character to A |
|||
CP CTRLC ;TEST CONTROL-C |
|||
JP Z,QUIT |
|||
CP CTRLX ;TEST CONTROL-X |
|||
JR Z,INCHA1 |
|||
CP CTRLW ;TEST CONTROL-W |
|||
JR Z,INCHA3 |
|||
CP CTRLY ;TEST CONTROL-Y |
|||
JR Z,INCHA2 |
|||
CP BS |
|||
RET Z |
|||
CP CR |
|||
RET Z |
|||
CP ' ' |
|||
JR C,INCON |
|||
JR INCH1 |
|||
; |
|||
INCHAR: CALL INCHA ;Input ASCII-Character to A |
|||
CP CTRLC ;TEST CONTROL-C |
|||
JR Z,QUIT |
|||
CP CTRLX ;TEST CONTROL-X |
|||
JR Z,INCHA1 |
|||
CP CTRLW ;TEST CONTROL-W |
|||
JR Z,INCHA3 |
|||
CP CTRLY ;TEST CONTROL-Y |
|||
JR Z,INCHA2 |
|||
CP BS |
|||
RET Z |
|||
CP CR |
|||
RET Z |
|||
CP ' ' |
|||
JR C,INCHAR ;Input invalied |
|||
; |
|||
INCH1: CP 'A' |
|||
RET C ;Character ok |
|||
; |
|||
RES 5,A ;lower case -> upper case |
|||
RET |
|||
INCHA1: POP HL |
|||
LD E,FF |
|||
CALL PCHAR ;Clear screen |
|||
JP GOON |
|||
INCHA2: POP HL |
|||
LD E,FF |
|||
CALL PCHAR ;Clear screen |
|||
JP GOON |
|||
INCHA3: LD E,FF |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;ABBRUCH DER BEARBEITUNG |
|||
;*********************** |
|||
; |
|||
COMPLT: LD DE,TCOMP |
|||
CALL PSTRIN |
|||
JP GOON |
|||
QUIT: CALL CRLF |
|||
LD DE,TQUIT |
|||
JR FINIS |
|||
INTTIM: POP DE ;STACK OK |
|||
; CALL DESAK |
|||
LD DE,TNMIAB |
|||
CALL PSTRIN |
|||
LD DE,MAIN ;NEW ADDRESS |
|||
PUSH DE |
|||
RETN |
|||
FINIS: CALL PSTRIN ;AT BDOS-ERROR |
|||
GOON: |
|||
JP BOOT |
|||
; |
|||
; |
|||
;TEXT-Messages |
|||
;************* |
|||
; |
|||
TCOMP: DEFB ESC,21,0,14H,ESC,23,0 |
|||
DEFM 'Function complete !!$' |
|||
TQUIT: DEFB ESC,23,0,14H,7 |
|||
DEFM 'End Run RAMFTEST$' |
|||
TNMIAB: DEFB ESC,23,0,14H |
|||
DEFM 'Time Out !!$' |
|||
; |
|||
; |
|||
INI_MSG:DEFM 'ECB-4PIO Init all PIO Bit-Mode ',CR,LF,'$' |
|||
PIO0ADW:DEFM 'ECB-4PIO Write to PIO0AD ','$' |
|||
PIO0ADR:DEFM 'ECB-4PIO Read from PIO0AD ','$' |
|||
PIO0BDW:DEFM 'ECB-4PIO Write to PIO0BD ','$' |
|||
PIO0BDR:DEFM 'ECB-4PIO Read from PIO0BD ','$' |
|||
PIO1ADW:DEFM 'ECB-4PIO Write to PIO1AD ','$' |
|||
PIO1ADR:DEFM 'ECB-4PIO Read from PIO1AD ','$' |
|||
PIO1BDW:DEFM 'ECB-4PIO Write to PIO1BD ','$' |
|||
PIO1BDR:DEFM 'ECB-4PIO Read from PIO1BD ','$' |
|||
|
|||
PIO_SRTMSG: |
|||
DEFM 'ECB-ZILOG PERIPHERALS start test 1.0',CR,LF,'$' |
|||
PIO_ENDMSG: |
|||
DEFM 'ECB-ZILOG PERIPHERALS end test 1.0',CR,LF,'$' |
|||
LINE_E: DEFM 'H',CR,LF,'$' |
|||
; |
|||
IF1 |
|||
.PRINTX 'Pass 1 complete' |
|||
ENDIF |
|||
; |
|||
IF2 |
|||
.PRINTX 'Pass 2 complete' |
|||
.PRINTX 'Assembly complete' |
|||
ENDIF |
|||
; |
|||
END |
|||
|
|||
@ -0,0 +1,13 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=..\..\..\..\Tools |
|||
|
|||
set PATH=%TOOLS%\zxcc;%PATH% |
|||
|
|||
set CPMDIR80=%TOOLS%/cpm/ |
|||
|
|||
zxcc M80 -=2piotst/l || exit /b |
|||
zxcc L80 -2piotst,2piotst.com/n/e || exit /b |
|||
|
|||
copy /Y 2piotst.com ..\..\..\..\Binary\Apps\Test\ || exit /b |
|||
@ -0,0 +1,8 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
if exist *.com del *.com |
|||
if exist *.lst del *.lst |
|||
if exist *.bin del *.bin |
|||
if exist *.rel del *.rel |
|||
if exist *.prn del *.prn |
|||
@ -0,0 +1,8 @@ |
|||
OBJECTS = 2piotst.com |
|||
DEST = ../../../../Binary/Apps/Test |
|||
TOOLS =../../../../Tools |
|||
OTHERS = *.rel |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
|
|||
2piotst.com : 2piotst.rel |
|||
@ -1 +1,8 @@ |
|||
DMAmon is a program to verify operation of the Z80 MBC DMA board |
|||
|
|||
Version 2 has been hacked to include testing for interrupts. This |
|||
requires running the application under RomWBW using IM2. There |
|||
is an equate in the source file to disable interrupt testing |
|||
if needed. |
|||
|
|||
--WBW 10:36 AM 3/14/2022 |
|||
@ -1,3 +0,0 @@ |
|||
~/RomWBW-dev/Tools/unix/uz80as/uz80as -t z80 dmamon.asm dmamon.bin |
|||
#srec_cat dmamon.bin -binary -offset 0x0100 --address-length=2 -o dmamon.hex -Intel |
|||
cat dmamon.bin > dmamon.com |
|||
@ -1,5 +1,5 @@ |
|||
OBJECTS = |
|||
SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz vdctest kbdtest kbdinfo |
|||
SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz vdctest kbdtest ps2info 2piotst piomon |
|||
DEST = ../../../Binary/Apps/Test |
|||
TOOLS =../../../Tools |
|||
|
|||
|
|||
@ -1,10 +0,0 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t180 -g3 -fFF kbdinfo.asm kbdinfo.com kbdinfo.lst || exit /b |
|||
|
|||
copy /Y kbdinfo.com ..\..\..\..\Binary\Apps\Test\ || exit /b |
|||
@ -1,896 +0,0 @@ |
|||
; |
|||
;======================================================================= |
|||
; Mouse Information Utility (MSEINFO) |
|||
;======================================================================= |
|||
; |
|||
; Simple utility that attempts to determine the status of the mouse you |
|||
; have attached to an 8242 keyboard controller. |
|||
; |
|||
; Based on Wayne Warthen's KBDINFO program, Thanks to his great work |
|||
; on RomWBW and support to the Retrobrewcomputers community at large |
|||
; |
|||
; Additional help from these websites |
|||
; https://isdaman.com/alsos/hardware/mouse/ps2interface.htm |
|||
; |
|||
; Second PS/2 write data port info from |
|||
; https://wiki.osdev.org/%228042%22_PS/2_Controller#Second_PS.2F2_Port |
|||
; |
|||
; PS/2 Mouse initialization code in C |
|||
; http://bos.asmhackers.net/docs/mouse/snippet_2/mouse.inc |
|||
; |
|||
;======================================================================= |
|||
; |
|||
; Mouse controller port addresses (adjust as needed) |
|||
; |
|||
iocmd .equ $E3 ; keyboard controller command port address |
|||
iodat .equ $E2 ; keyboard controller data port address |
|||
; |
|||
; General operational equates (should not requre adjustment) |
|||
; |
|||
stksiz .equ $40 ; Working stack size |
|||
; |
|||
timeout .equ $00 ; Controller timeout constant |
|||
; |
|||
restart .equ $0000 ; CP/M restart vector |
|||
bdos .equ $0005 ; BDOS invocation vector |
|||
; |
|||
;======================================================================= |
|||
; |
|||
.org $100 ; standard CP/M executable |
|||
; |
|||
; |
|||
; setup stack (save old value) |
|||
ld (stksav),sp ; save stack |
|||
ld sp,stack ; set new stack |
|||
; |
|||
call crlf |
|||
ld de,str_banner ; banner |
|||
call prtstr |
|||
; |
|||
call main ; do the real work |
|||
; |
|||
exit: |
|||
call crlf2 |
|||
ld de,str_exit |
|||
call prtstr |
|||
;call crlf |
|||
|
|||
; clean up and return to command processor |
|||
call crlf ; formatting |
|||
ld sp,(stksav) ; restore stack |
|||
jp restart ; return to CP/M via restart |
|||
; |
|||
; |
|||
;======================================================================= |
|||
; Main Program |
|||
;======================================================================= |
|||
; |
|||
main: |
|||
; |
|||
; Display active mouse controller port addresses |
|||
; |
|||
call crlf2 |
|||
ld de,str_cmdport |
|||
call prtstr |
|||
ld a,iocmd |
|||
call prthex |
|||
call crlf |
|||
ld de,str_dataport |
|||
call prtstr |
|||
ld a,iodat |
|||
call prthex |
|||
; |
|||
; Attempt self-test command on mouse controller |
|||
; |
|||
; Mouse controller should respond with an 0x55 on data port |
|||
; after being sent a 0xAA on the command port. |
|||
; |
|||
call crlf2 |
|||
ld de,str_ctrl_test |
|||
call prtstr |
|||
ld a,$aa ; self-test command |
|||
call put_cmd_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $55 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
; |
|||
; Send 0xA8 Mouse Enable command to 8242 controller |
|||
; |
|||
call crlf2 |
|||
ld de,str_enable_mouse |
|||
call prtstr |
|||
|
|||
ld a,$a8 ; Send Mouse Enable command to 8242 |
|||
call put_cmd_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for self-test status |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $AA ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $00 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
|
|||
|
|||
; |
|||
; Disable translation on keyboard controller to get raw scan codes! Enable Mouse |
|||
; |
|||
; call crlf2 |
|||
; ld de,str_trans_off |
|||
; call prtstr |
|||
; ld a,$60 ; write to command register 0 |
|||
; call put_cmd_dbg |
|||
; jp c,err_ctlr_io ; handle controller error |
|||
; ld a,$00 ; xlat disabled, mouse enabled, no ints |
|||
; call put_cmd_dbg |
|||
; jp c,err_ctlr_io ; handle controller error |
|||
|
|||
; Attempt four reset commands on mouse controller |
|||
; |
|||
call crlf2 |
|||
ld de,str_mse_init |
|||
call prtstr |
|||
|
|||
; Reset Pass #1 |
|||
ld a,$ff ; Send Mouse Reset command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
call get_data_dbg ; Read Mouse for self-test status |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $AA ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $00 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
; Reset Pass #2 |
|||
ld a,$ff ; Send Mouse Reset command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
call get_data_dbg ; Read Mouse for self-test status |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $AA ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $00 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
; Reset Pass #3 |
|||
ld a,$ff ; Send Mouse Reset command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
call get_data_dbg ; Read Mouse for self-test status |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $AA ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $00 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
; Reset Pass #4 |
|||
ld a,$ff ; Send Mouse Reset command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
call get_data_dbg ; Read Mouse for self-test status |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $AA ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $00 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
; Begin setting mouse parameters, Request Microsoft Scrolling Mouse Mode |
|||
|
|||
ld a,$f3 ; Send Set Sample Rate command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$c8 ; Send Decimal 200 command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$f3 ; Send Set Sample Rate command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$64 ; Send Decimal 100 command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$f3 ; Send Set Sample Rate command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$50 ; Send Decimal 80 command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$f2 ; Send Read Device Type command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $03 ; detect MS Intellimouse/Microsoft Scrolling Mouse |
|||
jp z,Intellimouse |
|||
cp $00 ; expected value? ($00 if Regular PS/2 Mouse) |
|||
jp z,ReadMouseID |
|||
Intellimouse: |
|||
call crlf |
|||
ld de,str_intellimouse_ok |
|||
call prtstr |
|||
ReadMouseID: |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
ld a,$f3 ; Send Set Sample Rate command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$0a ; Send Decimal 10 command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$f2 ; Send Read Device Type command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $03 ; detect MS Intellimouse/Microsoft Scrolling Mouse |
|||
jp z,Intellimouse2 |
|||
cp $00 ; expected value? ($00 if Regular PS/2 Mouse) |
|||
jp z,ReadMouseID2 |
|||
Intellimouse2: |
|||
call crlf |
|||
ld de,str_intellimouse_ok |
|||
call prtstr |
|||
ReadMouseID2: |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
|
|||
ld a,$e8 ; Send Set Resolution command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$03 ; Send 8 Counts/mm command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$e6 ; Send Set Scaling 1:1 command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$f3 ; Send Set Sample Rate command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$28 ; Send Decimal 40 command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
ld a,$f4 ; Send Enable command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
|
|||
call get_data_dbg ; Read Mouse for Acknowledge |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $fa ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
|
|||
; Initialization Complete |
|||
|
|||
ReadMousePackets: |
|||
|
|||
; call check_read |
|||
; jp nz, ReadMousePackets |
|||
|
|||
call get_data_dbg ; Read Mouse for self-test status |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call crlf |
|||
|
|||
call get_data_dbg ; Read Mouse for Mouse ID |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call crlf |
|||
|
|||
call crlf |
|||
|
|||
jp ReadMousePackets |
|||
|
|||
; |
|||
done: |
|||
ret |
|||
|
|||
; |
|||
;======================================================================= |
|||
; Mouse Controller I/O Routines |
|||
;======================================================================= |
|||
; |
|||
wait_write: |
|||
; |
|||
; Wait for mouse controller to be ready for a write |
|||
; A=0 indicates success (ZF set) |
|||
; |
|||
ld b,timeout ; setup timeout constant |
|||
wait_write1: |
|||
in a,(iocmd) ; get status |
|||
ld c,a ; save status |
|||
and $02 ; isolate input buf status bit |
|||
ret z ; 0 means ready, all done |
|||
call delay ; wait a bit |
|||
djnz wait_write1 ; loop until counter exhausted |
|||
ld de,str_timeout_write ; write timeout message |
|||
call crlf |
|||
call prtstr |
|||
ld a,c ; recover last status value |
|||
call prthex |
|||
or $ff ; signal error |
|||
ret |
|||
; |
|||
wait_read: |
|||
; |
|||
; Wait for mouse controller to be ready to read a byte |
|||
; A=0 indicates success (ZF set) |
|||
; |
|||
ld b,timeout ; setup timeout constant |
|||
wait_read1: |
|||
in a,(iocmd) ; get status |
|||
ld c,a ; save status |
|||
and $01 ; isolate input buf status bit |
|||
xor $01 ; invert so 0 means ready |
|||
ret z ; if 0, all done |
|||
call delay ; wait a bit |
|||
djnz wait_read1 ; loop until counter exhausted |
|||
ld de,str_timeout_read ; write timeout message |
|||
call crlf |
|||
call prtstr |
|||
ld a,c ; recover last status value |
|||
call prthex |
|||
or $ff ; signal error |
|||
ret |
|||
; |
|||
check_read: |
|||
; |
|||
; Check for data ready to read |
|||
; A=0 indicates data available (ZF set) |
|||
; |
|||
in a,(iocmd) ; get status |
|||
and $01 ; isolate input buf status bit |
|||
xor $01 ; invert so 0 means ready |
|||
ret |
|||
; |
|||
put_cmd: |
|||
; |
|||
; Put a cmd byte from A to the mouse interface with timeout |
|||
; CF set indicates timeout error |
|||
; |
|||
ld e,a ; save incoming value |
|||
call wait_write ; wait for controller ready |
|||
jr z,put_cmd1 ; if ready, move on |
|||
scf ; else, signal timeout error |
|||
ret ; and bail out |
|||
put_cmd1: |
|||
ld a,e ; recover value to write |
|||
out (iocmd),a ; write it |
|||
or a ; clear CF for success |
|||
ret |
|||
; |
|||
put_cmd_dbg: |
|||
call put_cmd |
|||
ret c |
|||
push af |
|||
call crlf |
|||
ld de,str_put_cmd |
|||
call prtstr |
|||
call prthex |
|||
pop af |
|||
ret |
|||
; |
|||
put_data: |
|||
; |
|||
; Put a data byte from A to the mouse interface with timeout |
|||
; CF set indicates timeout error |
|||
; |
|||
; note: direct data to second PS/2 port, send $d4 to 8242 command register |
|||
; different than keyboard which uses first PS/2 port |
|||
|
|||
push af ; save contents of a |
|||
ld e,a ; save incoming value |
|||
call wait_write ; wait for controller ready |
|||
jr z,put_data0 ; if ready, move on |
|||
scf ; else, signal timeout error |
|||
ret ; and bail out |
|||
put_data0: |
|||
ld a,$d4 ; direct to second PS/2 port for mouse |
|||
out (iocmd),a ; send second port command to 8242 |
|||
pop af |
|||
|
|||
; rest of put_data is the same as for PS/2 keyboard |
|||
|
|||
ld e,a ; save incoming value |
|||
call wait_write ; wait for controller ready |
|||
jr z,put_data1 ; if ready, move on |
|||
scf ; else, signal timeout error |
|||
ret ; and bail out |
|||
put_data1: |
|||
ld a,e ; recover value to write |
|||
out (iodat),a ; write it |
|||
or a ; clear CF for success |
|||
ret |
|||
; |
|||
put_data_dbg: |
|||
call put_data |
|||
ret c |
|||
push af |
|||
call crlf |
|||
ld de,str_put_data |
|||
call prtstr |
|||
call prthex |
|||
pop af |
|||
ret |
|||
|
|||
; |
|||
; Get a data byte from the mouse interface to A with timeout |
|||
; CF set indicates timeout error |
|||
; |
|||
get_data: |
|||
; |
|||
call wait_read ; wait for byte to be ready |
|||
jr z,get_data1 ; if ready, move on |
|||
scf ; else signal timeout error |
|||
ret ; and bail out |
|||
get_data1: |
|||
in a,(iodat) ; get data byte |
|||
or a ; clear CF for success |
|||
ret |
|||
; |
|||
get_data_dbg: |
|||
call get_data |
|||
ret c |
|||
push af |
|||
call crlf |
|||
ld de,str_get_data |
|||
call prtstr |
|||
call prthex |
|||
pop af |
|||
ret |
|||
; |
|||
; Error Handlers |
|||
; |
|||
err_ctlr_io: |
|||
ld de,str_err_ctrl_io |
|||
jr err_ret |
|||
; |
|||
err_ctlr_test: |
|||
ld de,str_err_ctrl_test |
|||
jr err_ret |
|||
; |
|||
err_mse_reset: |
|||
ld de,str_err_mse_reset |
|||
jr err_ret |
|||
; |
|||
err_ret: |
|||
call crlf2 |
|||
call prtstr |
|||
or $ff ; signal error |
|||
ret |
|||
; |
|||
;======================================================================= |
|||
; Utility Routines |
|||
;======================================================================= |
|||
; |
|||
; |
|||
; Print character in A without destroying any registers |
|||
; |
|||
prtchr: |
|||
push bc ; save registers |
|||
push de |
|||
push hl |
|||
ld e,a ; character to print in E |
|||
ld c,$02 ; BDOS function to output a character |
|||
call bdos ; do it |
|||
pop hl ; restore registers |
|||
pop de |
|||
pop bc |
|||
ret |
|||
; |
|||
prtdot: |
|||
; |
|||
; shortcut to print a dot preserving all regs |
|||
push af ; save af |
|||
ld a,'.' ; load dot char |
|||
call prtchr ; print it |
|||
pop af ; restore af |
|||
ret ; done |
|||
; |
|||
; Print a zero terminated string at (de) without destroying any registers |
|||
; |
|||
prtstr: |
|||
push af |
|||
push de |
|||
; |
|||
prtstr1: |
|||
ld a,(de) ; get next char |
|||
or a |
|||
jr z,prtstr2 |
|||
call prtchr |
|||
inc de |
|||
jr prtstr1 |
|||
; |
|||
prtstr2: |
|||
pop de ; restore registers |
|||
pop af |
|||
ret |
|||
; |
|||
; Print the value in A in hex without destroying any registers |
|||
; |
|||
prthex: |
|||
push af ; save AF |
|||
push de ; save DE |
|||
call hexascii ; convert value in A to hex chars in DE |
|||
ld a,d ; get the high order hex char |
|||
call prtchr ; print it |
|||
ld a,e ; get the low order hex char |
|||
call prtchr ; print it |
|||
pop de ; restore DE |
|||
pop af ; restore AF |
|||
ret ; done |
|||
; |
|||
; print the hex word value in hl |
|||
; |
|||
prthexword: |
|||
push af |
|||
ld a,h |
|||
call prthex |
|||
ld a,l |
|||
call prthex |
|||
pop af |
|||
ret |
|||
; |
|||
; print the hex dword value in de:hl |
|||
; |
|||
prthex32: |
|||
push bc |
|||
push de |
|||
pop bc |
|||
call prthexword |
|||
push hl |
|||
pop bc |
|||
call prthexword |
|||
pop bc |
|||
ret |
|||
; |
|||
; Convert binary value in A to ascii hex characters in DE |
|||
; |
|||
hexascii: |
|||
ld d,a ; save A in D |
|||
call hexconv ; convert low nibble of A to hex |
|||
ld e,a ; save it in E |
|||
ld a,d ; get original value back |
|||
rlca ; rotate high order nibble to low bits |
|||
rlca |
|||
rlca |
|||
rlca |
|||
call hexconv ; convert nibble |
|||
ld d,a ; save it in D |
|||
ret ; done |
|||
; |
|||
; Convert low nibble of A to ascii hex |
|||
; |
|||
hexconv: |
|||
and $0F ; low nibble only |
|||
add a,$90 |
|||
daa |
|||
adc a,$40 |
|||
daa |
|||
ret |
|||
; |
|||
; Print value of A or HL in decimal with leading zero suppression |
|||
; Use prtdecb for A or prtdecw for HL |
|||
; |
|||
prtdecb: |
|||
push hl |
|||
ld h,0 |
|||
ld l,a |
|||
call prtdecw ; print it |
|||
pop hl |
|||
ret |
|||
; |
|||
prtdecw: |
|||
push af |
|||
push bc |
|||
push de |
|||
push hl |
|||
call prtdec0 |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
pop af |
|||
ret |
|||
; |
|||
prtdec0: |
|||
ld e,'0' |
|||
ld bc,-10000 |
|||
call prtdec1 |
|||
ld bc,-1000 |
|||
call prtdec1 |
|||
ld bc,-100 |
|||
call prtdec1 |
|||
ld c,-10 |
|||
call prtdec1 |
|||
ld e,0 |
|||
ld c,-1 |
|||
prtdec1: |
|||
ld a,'0' - 1 |
|||
prtdec2: |
|||
inc a |
|||
add hl,bc |
|||
jr c,prtdec2 |
|||
sbc hl,bc |
|||
cp e |
|||
ret z |
|||
ld e,0 |
|||
call prtchr |
|||
ret |
|||
; |
|||
; Start a new line |
|||
; |
|||
crlf2: |
|||
call crlf ; two of them |
|||
crlf: |
|||
push af ; preserve AF |
|||
ld a,13 ; <CR> |
|||
call prtchr ; print it |
|||
ld a,10 ; <LF> |
|||
call prtchr ; print it |
|||
pop af ; restore AF |
|||
ret |
|||
; |
|||
; Brief delay |
|||
; |
|||
delay: |
|||
push bc |
|||
ld b,0 |
|||
delay1: |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
djnz delay1 |
|||
pop bc |
|||
ret |
|||
; |
|||
;======================================================================= |
|||
; Constants |
|||
;======================================================================= |
|||
; |
|||
str_banner .db "Mouse Information, v0.1",0 |
|||
str_exit .db "Done, Thank you for using MSEINFO!",0 |
|||
str_cmdport .db "Mouse Controller Command Port: 0x",0 |
|||
str_dataport .db "Mouse Controller Data Port: 0x",0 |
|||
str_timeout_write .db "Mouse Controller Write Timeout, Status: 0x",0 |
|||
str_timeout_read .db "Mouse Controller Read Timeout, Status: 0x",0 |
|||
str_err_ctrl_io .db "Mouse Controller I/O Failure",0 |
|||
str_err_ctrl_test .db "Mouse Controller Self-Test Failed",0 |
|||
str_put_cmd .db "Sent Command 0x",0 |
|||
str_put_data .db "Sent Data 0x",0 |
|||
str_get_data .db "Got Data 0x",0 |
|||
str_ctrl_test .db "Attempting Controller Self-Test",0 |
|||
str_mse_init .db "Attempting Mouse Initialization",0 |
|||
str_enable_mouse .db "Enabling Mouse in 8242 Controller",0 |
|||
str_ctrl_test_ok .db "Controller Self-Test OK",0 |
|||
str_intellimouse_ok .db "MS Intellimouse OK",0 |
|||
str_trans_off .db "Disabling Controller Translation",0 |
|||
str_mse_reset .db "Attempting Mouse Reset",0 |
|||
str_mse_reset_ok .db "Mouse Reset OK",0 |
|||
str_err_mse_reset .db "Mouse Reset Failed",0 |
|||
; |
|||
;======================================================================= |
|||
; Working data |
|||
;======================================================================= |
|||
; |
|||
stksav .dw 0 ; stack pointer saved at start |
|||
.fill stksiz,0 ; stack |
|||
stack .equ $ ; stack top |
|||
; |
|||
workbuf .fill 8 |
|||
workbuf_len .db 0 |
|||
; |
|||
;======================================================================= |
|||
; |
|||
.end |
|||
|
|||
@ -0,0 +1,10 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t180 -g3 -fFF piomon.asm piomon.com piomon.lst || exit /b |
|||
|
|||
copy /Y piomon.com ..\..\..\..\Binary\Apps\Test\ || exit /b |
|||
@ -1,4 +1,4 @@ |
|||
OBJECTS = kbdinfo.com |
|||
OBJECTS = piomon.com |
|||
DEST = ../../../../Binary/Apps/Test |
|||
TOOLS =../../../../Tools |
|||
|
|||
@ -0,0 +1,36 @@ |
|||
PIOMON is a program to verify operation of the Z80 MBC DUALPIO board |
|||
|
|||
Most testing requires the use of loopback hardware constructed as: |
|||
|
|||
Channel A RDY STB D0 D1 D2 D3 D4 D5 D6 D7 |
|||
\ / | | | | | | | | |
|||
\ / | | | | | | | | |
|||
X | | | | | | | | |
|||
/ \ | | | | | | | | |
|||
/ \ | | | | | | | | |
|||
Channel B RDY STB D0 D1 D2 D3 D4 D5 D6 D7 |
|||
|
|||
The DUALPIO has, well, 2 PIO chips. Only one chip |
|||
is tested at a time. At startup, PIOMON will ask |
|||
you for the port of the chip to test. It defaults |
|||
to the standard port number for the primary PIO chip |
|||
on an MBC DUALPIO board. |
|||
|
|||
The port number specified is the base I/O port. Each |
|||
chip has two channels which are addressed in the |
|||
menu by specifying A or B. |
|||
|
|||
MBC DUALPIO Primary PIO = 0xB8 |
|||
MBC DUALPIO Secondary PIO = 0xBC |
|||
|
|||
If you try to use PIOMON without the RDY and STB |
|||
cross connected, you may have interrupt issues |
|||
because STB will be floating. |
|||
|
|||
N.B., V1 and V2 of the DUALPIO lack a hardware reset. The |
|||
PIO chips will reset at power-on, but they do not reset |
|||
when the reset button is pushed. |
|||
|
|||
Happy St. Patrick's Day!!! |
|||
|
|||
--WBW 7:42 PM 3/17/2022 |
|||
File diff suppressed because it is too large
@ -0,0 +1,10 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t180 -g3 -fFF ps2info.asm ps2info.com ps2info.lst || exit /b |
|||
|
|||
copy /Y ps2info.com ..\..\..\..\Binary\Apps\Test\ || exit /b |
|||
@ -0,0 +1,6 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
if exist *.com del *.com |
|||
if exist *.lst del *.lst |
|||
if exist *.bin del *.bin |
|||
@ -0,0 +1,7 @@ |
|||
OBJECTS = ps2info.com |
|||
DEST = ../../../../Binary/Apps/Test |
|||
TOOLS =../../../../Tools |
|||
|
|||
USETASM=1 |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
Binary file not shown.
@ -0,0 +1,10 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t180 -g3 -fFF cpuspd.asm cpuspd.com cpuspd.lst || exit /b |
|||
|
|||
copy /Y cpuspd.com ..\..\..\Binary\Apps\ || exit /b |
|||
@ -0,0 +1,6 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
if exist *.com del *.com |
|||
if exist *.lst del *.lst |
|||
if exist *.bin del *.bin |
|||
@ -0,0 +1,7 @@ |
|||
OBJECTS = cpuspd.com |
|||
DEST = ../../../Binary/Apps |
|||
TOOLS =../../../Tools |
|||
|
|||
USETASM=1 |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
@ -0,0 +1,707 @@ |
|||
; |
|||
;======================================================================= |
|||
; HBIOS CPU Speed Selection Tool |
|||
;======================================================================= |
|||
; |
|||
; Simple utility that sets CPU speed on RomWBW systems that support |
|||
; software speed selection. |
|||
; |
|||
;======================================================================= |
|||
; |
|||
#include "../../HBIOS/hbios.inc" |
|||
; |
|||
; General operational equates (should not requre adjustment) |
|||
; |
|||
stksiz .equ $40 ; Working stack size |
|||
; |
|||
cpumhz .equ 30 ; for time delay calculations (not critical) |
|||
; |
|||
rtc_port .equ $70 ; RTC latch port adr |
|||
; |
|||
restart .equ $0000 ; CP/M restart vector |
|||
bdos .equ $0005 ; BDOS invocation vector |
|||
; |
|||
ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr |
|||
; |
|||
rmj .equ 3 ; intended CBIOS version - major |
|||
rmn .equ 1 ; intended CBIOS version - minor |
|||
; |
|||
;======================================================================= |
|||
; |
|||
.org $100 ; standard CP/M executable |
|||
; |
|||
; |
|||
; setup stack (save old value) |
|||
ld (stksav),sp ; save stack |
|||
ld sp,stack ; set new stack |
|||
; |
|||
call crlf |
|||
ld de,str_banner ; banner |
|||
call prtstr |
|||
; |
|||
; initialization |
|||
call init ; initialize |
|||
jr nz,exit ; abort if init fails |
|||
; |
|||
call main ; do the real work |
|||
; |
|||
exit: |
|||
; clean up and return to command processor |
|||
call crlf ; formatting |
|||
ld sp,(stksav) ; restore stack |
|||
jp restart ; return to CP/M via restart |
|||
; |
|||
; |
|||
;======================================================================= |
|||
; Main Program |
|||
;======================================================================= |
|||
; |
|||
; |
|||
; Initialization |
|||
; |
|||
init: |
|||
; check for UNA (UBIOS) |
|||
ld a,($FFFD) ; fixed location of UNA API vector |
|||
cp $C3 ; jp instruction? |
|||
jr nz,initwbw ; if not, not UNA |
|||
ld hl,($FFFE) ; get jp address |
|||
ld a,(hl) ; get byte at target address |
|||
cp $FD ; first byte of UNA push ix instruction |
|||
jr nz,initwbw ; if not, not UNA |
|||
inc hl ; point to next byte |
|||
ld a,(hl) ; get next byte |
|||
cp $E5 ; second byte of UNA push ix instruction |
|||
jr nz,initwbw ; if not, not UNA |
|||
jp err_una ; UNA not supported |
|||
; |
|||
initwbw: |
|||
; get location of config data and verify integrity |
|||
ld hl,(ident) ; HL := adr or RomWBW HBIOS ident |
|||
ld a,(hl) ; get first byte of RomWBW marker |
|||
cp 'W' ; match? |
|||
jp nz,err_inv ; abort with invalid config block |
|||
inc hl ; next byte (marker byte 2) |
|||
ld a,(hl) ; load it |
|||
cp ~'W' ; match? |
|||
jp nz,err_inv ; abort with invalid config block |
|||
inc hl ; next byte (major/minor version) |
|||
ld a,(hl) ; load it |
|||
cp rmj << 4 | rmn ; match? |
|||
jp nz,err_ver ; abort with invalid os version |
|||
; |
|||
initz: |
|||
; initialization complete |
|||
xor a ; signal success |
|||
ret ; return |
|||
; |
|||
; |
|||
; |
|||
main: |
|||
; skip to start of first parm |
|||
ld ix,$81 ; point to start of parm area (past len byte) |
|||
call nonblank ; skip to next non-blank char |
|||
jp z,show_spd ; no parms, show current settings |
|||
; |
|||
main1: |
|||
; process options (if any) |
|||
cp '/' ; option prefix? |
|||
jr nz,main2 ; not an option, continue |
|||
call option ; process option |
|||
ret nz ; some options mean we are done (e.g., "/?") |
|||
inc ix ; skip option character |
|||
call nonblank ; skip whitespace |
|||
jr main1 ; continue option checking |
|||
; |
|||
main2: |
|||
ret z ; if end, nothing to do |
|||
cp ',' ; no new speed? |
|||
jr z,main2a ; go to wait states |
|||
; parse speed string (half, full, double) |
|||
call getalpha ; extract speed ("HALF", "FULL", "DOUBLE") |
|||
call parse_spd ; parse to numeric |
|||
jp c,err_parm ; if invalid, abort |
|||
ld (new_cpu_spd),a ; save it |
|||
call nonblank ; skip whitespace |
|||
jp z,set_spd ; if nothing else, set new speed |
|||
cp ',' ; parm separator |
|||
jp nz,err_parm ; invalid format, show usage and abort |
|||
main2a: |
|||
inc ix ; pass separator |
|||
call nonblank ; skip whitespace |
|||
jp z,set_spd ; if nothing else, set new speed |
|||
call isnum ; start of parm? |
|||
jr c,main3 ; nope, try skipping this parm |
|||
call getnum ; get memory wait states |
|||
jp c,err_parm ; if overflow, show usage and abort |
|||
ld (new_ws_mem),a ; save memory wait states |
|||
; |
|||
main3: |
|||
call nonblank ; skip whitespace |
|||
jp z,set_spd ; if nothing else, set new speed |
|||
cp ',' ; parm separator |
|||
jp nz,err_parm ; invalid format, show usage and abort |
|||
inc ix ; pass separator |
|||
call nonblank ; skip whitespace |
|||
jp z,set_spd ; if nothing else, set new speed |
|||
call getnum ; get I/O wait states |
|||
jp c,err_parm ; if overflow, show usage and abort |
|||
ld (new_ws_io),a ; save memory wait states |
|||
; |
|||
call nonblank ; skip whitespace |
|||
jp nz,err_parm ; invalid format, show usage and abort |
|||
jp set_spd ; set new speed and return |
|||
; |
|||
parse_spd: |
|||
ld a,(tmpstr) ; first byte of string |
|||
ld c,0 ; assume half speed |
|||
cp 'H' ; check it |
|||
jr z,parse_spd1 ; if equal, done |
|||
ld c,1 ; assume full speed |
|||
cp 'F' ; check it |
|||
jr z,parse_spd1 ; if equal, done |
|||
ld c,2 ; assume double speed |
|||
cp 'D' ; check it |
|||
jr z,parse_spd1 ; if equal, done |
|||
or a ; clear CF |
|||
ccf ; set CF to indicate error |
|||
ret |
|||
parse_spd1: |
|||
ld a,c ; result to a |
|||
or a ; clear CF |
|||
ret |
|||
; |
|||
set_spd: |
|||
call delay |
|||
ld b,BF_SYSSET |
|||
ld c,BF_SYSSET_CPUSPD |
|||
ld a,(new_cpu_spd) |
|||
ld l,a |
|||
ld a,(new_ws_mem) |
|||
ld d,a |
|||
ld a,(new_ws_io) |
|||
ld e,a |
|||
rst 08 |
|||
jp nz,err_not_sup |
|||
call show_spd |
|||
xor a |
|||
ret |
|||
; |
|||
show_spd: |
|||
ld b,BF_SYSGET |
|||
ld c,BF_SYSGET_CPUINFO |
|||
rst 08 |
|||
jp nz,err_not_sup |
|||
call crlf2 |
|||
push de ; save CPU speed for now |
|||
push bc ; Oscillator speed to HL |
|||
pop hl |
|||
ld de,str_spacer |
|||
call prtstr |
|||
call prtd3m ; print it |
|||
ld de,str_oscspd |
|||
call prtstr |
|||
ld b,BF_SYSGET |
|||
ld c,BF_SYSGET_CPUSPD |
|||
rst 08 |
|||
jp nz,err_not_sup |
|||
push de |
|||
ld a,l |
|||
ld de,str_slow |
|||
cp 0 |
|||
jr z,show_spd1 |
|||
ld de,str_full |
|||
cp 1 |
|||
jr z,show_spd1 |
|||
ld de,str_dbl |
|||
cp 2 |
|||
jr z,show_spd1 |
|||
jp err_invalid |
|||
show_spd1: |
|||
call crlf |
|||
call prtstr |
|||
pop bc ; recover wait states |
|||
pop hl ; recover CPU speed |
|||
push bc ; resave wait states |
|||
call prtd3m |
|||
ld de,str_cpuspd |
|||
call prtstr |
|||
pop hl |
|||
ld a,h ; memory wait states |
|||
cp $FF |
|||
jr z,show_spd2 |
|||
call crlf |
|||
ld de,str_spacer |
|||
call prtstr |
|||
call prtdecb |
|||
ld de,str_memws |
|||
call prtstr |
|||
; |
|||
show_spd2: |
|||
ld a,l |
|||
cp $FF |
|||
jr z,show_spd3 |
|||
call crlf |
|||
ld de,str_spacer |
|||
call prtstr |
|||
call prtdecb |
|||
ld de,str_iows |
|||
call prtstr |
|||
; |
|||
show_spd3: |
|||
ret |
|||
; |
|||
; Handle special options |
|||
; |
|||
option: |
|||
; |
|||
inc ix ; next char |
|||
ld a,(ix) ; get it |
|||
cp '?' ; is it a '?' as expected? |
|||
jp z,usage ; yes, display usage |
|||
jp err_parm ; anything else is an error |
|||
|
|||
usage: |
|||
call crlf2 |
|||
ld de,str_usage |
|||
call prtstr |
|||
or $FF |
|||
ret |
|||
; |
|||
; Error Handlers |
|||
; |
|||
err_una: |
|||
ld de,str_err_una |
|||
jr err_ret |
|||
err_inv: |
|||
ld de,str_err_inv |
|||
jr err_ret |
|||
err_ver: |
|||
ld de,str_err_ver |
|||
jr err_ret |
|||
err_parm: |
|||
ld de,str_err_parm |
|||
jr err_ret |
|||
err_not_sup: |
|||
ld de,str_err_not_sup |
|||
jr err_ret |
|||
err_invalid: |
|||
ld de,str_err_invalid |
|||
jr err_ret |
|||
; |
|||
err_ret: |
|||
call crlf2 |
|||
call prtstr |
|||
or $FF ; signal error |
|||
ret |
|||
; |
|||
;======================================================================= |
|||
; Utility Routines |
|||
;======================================================================= |
|||
; |
|||
; |
|||
; Print character in A without destroying any registers |
|||
; |
|||
prtchr: |
|||
push af |
|||
push bc ; save registers |
|||
push de |
|||
push hl |
|||
ld e,a ; character to print in E |
|||
ld c,$02 ; BDOS function to output a character |
|||
call bdos ; do it |
|||
pop hl ; restore registers |
|||
pop de |
|||
pop bc |
|||
pop af |
|||
ret |
|||
; |
|||
; Print a dot character without destroying any registers |
|||
; |
|||
prtdot: |
|||
; shortcut to print a dot preserving all regs |
|||
push af ; save af |
|||
ld a,'.' ; load dot char |
|||
call prtchr ; print it |
|||
pop af ; restore af |
|||
ret ; done |
|||
; |
|||
; Print a zero terminated string at (de) without destroying any registers |
|||
; |
|||
prtstr: |
|||
push af |
|||
push de |
|||
; |
|||
prtstr1: |
|||
ld a,(de) ; get next char |
|||
or a |
|||
jr z,prtstr2 |
|||
call prtchr |
|||
inc de |
|||
jr prtstr1 |
|||
; |
|||
prtstr2: |
|||
pop de ; restore registers |
|||
pop af |
|||
ret |
|||
; |
|||
; Print a hex value prefix "0x" |
|||
; |
|||
prthexpre: |
|||
push af |
|||
ld a,'0' |
|||
call prtchr |
|||
ld a,'x' |
|||
call prtchr |
|||
pop af |
|||
ret |
|||
; |
|||
; Print the value in A in hex without destroying any registers |
|||
; |
|||
prthex: |
|||
call prthexpre |
|||
prthex1: |
|||
push af ; save AF |
|||
push de ; save DE |
|||
call hexascii ; convert value in A to hex chars in DE |
|||
ld a,d ; get the high order hex char |
|||
call prtchr ; print it |
|||
ld a,e ; get the low order hex char |
|||
call prtchr ; print it |
|||
pop de ; restore DE |
|||
pop af ; restore AF |
|||
ret ; done |
|||
; |
|||
; print the hex word value in hl |
|||
; |
|||
prthexword: |
|||
call prthexpre |
|||
prthexword1: |
|||
push af |
|||
ld a,h |
|||
call prthex1 |
|||
ld a,l |
|||
call prthex1 |
|||
pop af |
|||
ret |
|||
; |
|||
; print the hex dword value in de:hl |
|||
; |
|||
prthex32: |
|||
call prthexpre |
|||
push bc |
|||
push de |
|||
pop bc |
|||
call prthexword1 |
|||
push hl |
|||
pop bc |
|||
call prthexword1 |
|||
pop bc |
|||
ret |
|||
; |
|||
; Convert binary value in A to ascii hex characters in DE |
|||
; |
|||
hexascii: |
|||
ld d,a ; save A in D |
|||
call hexconv ; convert low nibble of A to hex |
|||
ld e,a ; save it in E |
|||
ld a,d ; get original value back |
|||
rlca ; rotate high order nibble to low bits |
|||
rlca |
|||
rlca |
|||
rlca |
|||
call hexconv ; convert nibble |
|||
ld d,a ; save it in D |
|||
ret ; done |
|||
; |
|||
; Convert low nibble of A to ascii hex |
|||
; |
|||
hexconv: |
|||
and $0F ; low nibble only |
|||
add a,$90 |
|||
daa |
|||
adc a,$40 |
|||
daa |
|||
ret |
|||
; |
|||
; Print value of A or HL in decimal with leading zero suppression |
|||
; Use prtdecb for A or prtdecw for HL |
|||
; |
|||
prtdecb: |
|||
push hl |
|||
ld h,0 |
|||
ld l,a |
|||
call prtdecw ; print it |
|||
pop hl |
|||
ret |
|||
; |
|||
prtdecw: |
|||
push af |
|||
push bc |
|||
push de |
|||
push hl |
|||
call prtdec0 |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
pop af |
|||
ret |
|||
; |
|||
prtdec0: |
|||
ld e,'0' |
|||
ld bc,-10000 |
|||
call prtdec1 |
|||
ld bc,-1000 |
|||
call prtdec1 |
|||
ld bc,-100 |
|||
call prtdec1 |
|||
ld c,-10 |
|||
call prtdec1 |
|||
ld e,0 |
|||
ld c,-1 |
|||
prtdec1: |
|||
ld a,'0' - 1 |
|||
prtdec2: |
|||
inc a |
|||
add hl,bc |
|||
jr c,prtdec2 |
|||
sbc hl,bc |
|||
cp e |
|||
ret z |
|||
ld e,0 |
|||
call prtchr |
|||
ret |
|||
; |
|||
; Print value of HL as thousandths, ie. 0.000 |
|||
; |
|||
prtd3m: |
|||
push bc |
|||
push de |
|||
push hl |
|||
ld e,'0' |
|||
ld bc,-10000 |
|||
call prtd3m1 |
|||
ld e,0 |
|||
ld bc,-1000 |
|||
call prtd3m1 |
|||
call prtdot |
|||
ld bc,-100 |
|||
call prtd3m1 |
|||
ld c,-10 |
|||
call prtd3m1 |
|||
ld c,-1 |
|||
call prtd3m1 |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
ret |
|||
prtd3m1: |
|||
ld a,'0' - 1 |
|||
prtd3m2: |
|||
inc a |
|||
add hl,bc |
|||
jr c,prtd3m2 |
|||
sbc hl,bc |
|||
cp e |
|||
jr z,prtd3m3 |
|||
ld e,0 |
|||
call prtchr |
|||
prtd3m3: |
|||
ret |
|||
|
|||
|
|||
|
|||
; |
|||
; Get the next non-blank character from (HL). |
|||
; |
|||
nonblank: |
|||
ld a,(ix) ; load next character |
|||
or a ; string ends with a null |
|||
ret z ; if null, return pointing to null |
|||
cp ' ' ; check for blank |
|||
ret nz ; return if not blank |
|||
inc ix ; if blank, increment character pointer |
|||
jr nonblank ; and loop |
|||
; |
|||
; Get alpha chars and save in tmpstr |
|||
; Length of string returned in A |
|||
; |
|||
getalpha: |
|||
; |
|||
ld hl,tmpstr ; location to save chars |
|||
ld b,8 ; length counter (tmpstr max chars) |
|||
ld c,0 ; init character counter |
|||
; |
|||
getalpha1: |
|||
ld a,(ix) ; get active char |
|||
call ucase ; lower case -> uppper case, if needed |
|||
cp 'A' ; check for start of alpha range |
|||
jr c,getalpha2 ; not alpha, get out |
|||
cp 'Z' + 1 ; check for end of alpha range |
|||
jr nc,getalpha2 ; not alpha, get out |
|||
; handle alpha char |
|||
ld (hl),a ; save it |
|||
inc c ; bump char count |
|||
inc hl ; inc string pointer |
|||
inc ix ; increment buffer ptr |
|||
djnz getalpha1 ; if space, loop for more chars |
|||
; |
|||
getalpha2: ; non-alpha, clean up and return |
|||
ld (hl),0 ; terminate string |
|||
ld a,c ; string length to A |
|||
or a ; set flags |
|||
ret ; and return |
|||
; |
|||
; Determine if byte in A is a numeric '0'-'9' |
|||
; Return with CF clear if it is numeric |
|||
; |
|||
isnum: |
|||
cp '0' |
|||
jr c,isnum1 ; too low |
|||
cp '9' + 1 |
|||
jr nc,isnum1 ; too high |
|||
or a ; clear CF |
|||
ret |
|||
isnum1: |
|||
or a ; clear CF |
|||
ccf ; set CF |
|||
ret |
|||
|
|||
; |
|||
; Get numeric chars and convert to number returned in A |
|||
; Carry flag set on overflow |
|||
; |
|||
getnum: |
|||
ld c,0 ; C is working register |
|||
getnum1: |
|||
ld a,(ix) ; get the active char |
|||
cp '0' ; compare to ascii '0' |
|||
jr c,getnum2 ; abort if below |
|||
cp '9' + 1 ; compare to ascii '9' |
|||
jr nc,getnum2 ; abort if above |
|||
; |
|||
; valid digit, add new digit to C |
|||
ld a,c ; get working value to A |
|||
rlca ; multiply by 10 |
|||
ret c ; overflow, return with carry set |
|||
rlca ; ... |
|||
ret c ; overflow, return with carry set |
|||
add a,c ; ... |
|||
ret c ; overflow, return with carry set |
|||
rlca ; ... |
|||
ret c ; overflow, return with carry set |
|||
ld c,a ; back to C |
|||
ld a,(ix) ; get new digit |
|||
sub '0' ; make binary |
|||
add a,c ; add in working value |
|||
ret c ; overflow, return with carry set |
|||
ld c,a ; back to C |
|||
; |
|||
inc ix ; bump to next char |
|||
jr getnum1 ; loop |
|||
; |
|||
getnum2: ; return result |
|||
ld a,c ; return result in A |
|||
or a ; with flags set, CF is cleared |
|||
ret |
|||
; |
|||
; Start a new line |
|||
; |
|||
crlf2: |
|||
call crlf ; two of them |
|||
crlf: |
|||
push af ; preserve AF |
|||
ld a,13 ; <CR> |
|||
call prtchr ; print it |
|||
ld a,10 ; <LF> |
|||
call prtchr ; print it |
|||
pop af ; restore AF |
|||
ret |
|||
; |
|||
; Convert character in A to uppercase |
|||
; |
|||
ucase: |
|||
cp 'a' ; if below 'a' |
|||
ret c ; ... do nothing and return |
|||
cp 'z' + 1 ; if above 'z' |
|||
ret nc ; ... do nothing and return |
|||
res 5,a ; clear bit 5 to make lower case -> upper case |
|||
ret ; and return |
|||
; |
|||
; Add hl,a |
|||
; |
|||
; A register is destroyed! |
|||
; |
|||
addhla: |
|||
add a,l |
|||
ld l,a |
|||
ret nc |
|||
inc h |
|||
ret |
|||
; |
|||
; Delay ~10ms |
|||
; |
|||
delay: |
|||
push af |
|||
push de |
|||
ld de,625 ; 10000us/16us |
|||
delay0: |
|||
ld a,cpumhz - 2 |
|||
delay1: |
|||
dec a |
|||
jr nz,delay1 |
|||
dec de |
|||
ld a,d |
|||
or e |
|||
jp nz,delay0 |
|||
pop de |
|||
pop af |
|||
ret |
|||
; |
|||
; |
|||
;======================================================================= |
|||
; Constants |
|||
;======================================================================= |
|||
; |
|||
str_banner .db "RomWBW CPU Speed Selector v0.5, 2-Feb-2022",0 |
|||
str_spacer .db " ",0 |
|||
str_oscspd .db " MHz Oscillator",0 |
|||
str_slow .db " CPU speed is HALF (",0 |
|||
str_full .db " CPU speed is FULL (",0 |
|||
str_dbl .db " CPU speed is DOUBLE (",0 |
|||
str_cpuspd .db " MHz)",0 |
|||
str_memws .db " Memory Wait State(s)",0 |
|||
str_iows .db " I/O Wait State(s)",0 |
|||
str_err_una .db " ERROR: UNA not supported by application",0 |
|||
str_err_inv .db " ERROR: Invalid BIOS (signature missing)",0 |
|||
str_err_ver .db " ERROR: Unexpected HBIOS version",0 |
|||
str_err_parm .db " ERROR: Parameter error (CPUSPD /? for usage)",0 |
|||
str_err_not_sup .db " ERROR: Platform or configuration not supported!",0 |
|||
str_err_invalid .db " ERROR: Invalid configuration!",0 |
|||
str_usage .db " Usage: CPUSPD <cpuspd>,<memws>,<iows>\r\n" |
|||
.db "\r\n" |
|||
.db " <cpuspd>: \"Half\", \"Full\", or \"Double\"\r\n" |
|||
.db " <memws>: Memory wait states\r\n" |
|||
.db " <iows>: I/O wait states\r\n" |
|||
.db "\r\n" |
|||
.db " Any parameter may be omitted\r\n" |
|||
.db " Ability to set values varies by system\r\n",0 |
|||
; |
|||
;======================================================================= |
|||
; Working data |
|||
;======================================================================= |
|||
; |
|||
stksav .dw 0 ; stack pointer saved at start |
|||
.fill stksiz,0 ; stack |
|||
stack .equ $ ; stack top |
|||
; |
|||
; |
|||
tmpstr .fill 9,0 ; temp string (8 chars, 0 term) |
|||
new_cpu_spd .db $FF ; new CPU speed |
|||
new_ws_mem .db $FF ; new memory wait states |
|||
new_ws_io .db $FF ; new I/O wait states |
|||
|
|||
|
|||
; |
|||
;======================================================================= |
|||
; |
|||
.end |
|||
@ -1,13 +1,11 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set PATH=%PATH%;..\..\..\Tools\zx;..\..\..\Tools\cpmtools; |
|||
set PATH=%PATH%;..\..\..\Tools\zxcc;..\..\..\Tools\cpmtools; |
|||
|
|||
set ZXBINDIR=../../../tools/cpm/bin/ |
|||
set ZXLIBDIR=../../../tools/cpm/lib/ |
|||
set ZXINCDIR=../../../tools/cpm/include/ |
|||
set CPMDIR80=%TOOLS%/cpm/ |
|||
|
|||
copy ..\z3base.lib . || exit /b |
|||
zx ZMAC -zcpr33.z80 -/P || exit /b |
|||
zxcc ZMAC -zcpr33.z80 -/P || exit /b |
|||
del z3base.lib || exit /b |
|||
move zcpr33.rel .. || exit /b |
|||
@ -0,0 +1,54 @@ |
|||
; |
|||
;================================================================================================== |
|||
; RC2014 Z80 ZRC CONFIGURATION |
|||
;================================================================================================== |
|||
; |
|||
; THE COMPLETE SET OF DEFAULT CONFIGURATION SETTINGS FOR THIS PLATFORM ARE FOUND IN THE |
|||
; CFG_<PLT>.ASM INCLUDED FILE WHICH IS FOUND IN THE PARENT DIRECTORY. THIS FILE CONTAINS |
|||
; COMMON CONFIGURATION SETTINGS THAT OVERRIDE THE DEFAULTS. IT IS INTENDED THAT YOU MAKE |
|||
; YOUR CUSTOMIZATIONS IN THIS FILE AND JUST INHERIT ALL OTHER SETTINGS FROM THE DEFAULTS. |
|||
; EVEN BETTER, YOU CAN MAKE A COPY OF THIS FILE WITH A NAME LIKE <PLT>_XXX.ASM AND SPECIFY |
|||
; YOUR FILE IN THE BUILD PROCESS. |
|||
; |
|||
; THE SETTINGS BELOW ARE THE SETTINGS THAT ARE MOST COMMONLY MODIFIED FOR THIS PLATFORM. |
|||
; MANY OF THEM ARE EQUAL TO THE SETTINGS IN THE INCLUDED FILE, SO THEY DON'T REALLY DO |
|||
; ANYTHING AS IS. THEY ARE LISTED HERE TO MAKE IT EASY FOR YOU TO ADJUST THE MOST COMMON |
|||
; SETTINGS. |
|||
; |
|||
; N.B., SINCE THE SETTINGS BELOW ARE REDEFINING VALUES ALREADY SET IN THE INCLUDED FILE, |
|||
; TASM INSISTS THAT YOU USE THE .SET OPERATOR AND NOT THE .EQU OPERATOR BELOW. ATTEMPTING |
|||
; TO REDEFINE A VALUE WITH .EQU BELOW WILL CAUSE TASM ERRORS! |
|||
; |
|||
; PLEASE REFER TO THE CUSTOM BUILD INSTRUCTIONS (README.TXT) IN THE SOURCE DIRECTORY (TWO |
|||
; DIRECTORIES ABOVE THIS ONE). |
|||
; |
|||
#DEFINE BOOT_DEFAULT "H" ; DEFAULT BOOT LOADER CMD ON <CR> OR AUTO BOOT |
|||
; |
|||
#include "cfg_rcz80.asm" |
|||
; |
|||
CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP |
|||
; |
|||
CPUOSC .SET 7372800 ; CPU OSC FREQ IN MHZ |
|||
; |
|||
RAMSIZE .SET 2048 ; SIZE OF RAM IN KB (MUST MATCH YOUR HARDWARE!!!) |
|||
MEMMGR .SET MM_ZRC ; MEMORY MANAGER: MM_[SBC|Z2|N8|Z180] |
|||
; |
|||
MDROM .SET FALSE ; MD: ENABLE ROM DISK |
|||
; |
|||
UARTENABLE .SET TRUE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) |
|||
ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) |
|||
SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) |
|||
; |
|||
TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) |
|||
TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) |
|||
; |
|||
AY38910ENABLE .SET TRUE ; AY: AY-3-8910 / YM2149 SOUND DRIVER |
|||
; |
|||
FDENABLE .SET TRUE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) |
|||
FDMODE .SET FDMODE_RCWDC ; FD: DRIVER MODE: FDMODE_[DIO|ZETA|ZETA2|DIDE|N8|DIO3|RCSMC|RCWDC|DYNO|EPWDC] |
|||
; |
|||
IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) |
|||
; |
|||
PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) |
|||
; |
|||
PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,999 @@ |
|||
; PIO driver sets up the parallel port as a subtype of Serial/Char device. |
|||
; |
|||
; |
|||
; HBIOS initializes driver by: |
|||
; |
|||
; 1) Calling Pre-initialization |
|||
; |
|||
; This involves setting up all the data structures describing the devices. |
|||
; If possible, do a hardware test to verify it is available for adding to available devices. |
|||
; |
|||
; 2) Calling device initialization. |
|||
; |
|||
; Hardware initialization. |
|||
; Configure to initial state or to a new state. |
|||
; |
|||
; Implementation limitations: |
|||
; |
|||
; The fully functionality of the Z80 PIO can only be realized by using Z80 interrupt mode 2. |
|||
; Registers cannot be interrogated for interrupts status and the originating interrupt |
|||
; device cannot be determine. |
|||
; |
|||
; Full implementation of IM2 functionality for an ECB-ZP and ECB-4P board would require the |
|||
; allocation of an interrupt handler for each chip channel. Thus, 12 interrupt handlers |
|||
; would be required to support this configuration. As the HBIOS only has an allocation of |
|||
; 16, a full implmentation is impractical. |
|||
; |
|||
; The compromise solution is to allow 4 interrupts for the PIO driver. All remaining PIO's |
|||
; are limited to Bit mode or blind read and write to the input/output ports. |
|||
; |
|||
; Zilog PIO reset state: |
|||
; |
|||
; Both port mask registers are reset to inhibit All port data bits. |
|||
; Port data bus lines are set to a high-impedance state and the Ready "handshake" |
|||
; Mode 1 (output) is automatically selected. |
|||
; The vector address registers are not reset. |
|||
; Both port interrupt enable flip-flops are reset. |
|||
; Both port output registers are reset. |
|||
; |
|||
; Register addressing example for ECB-ZP and ECB-4P assuming base address 90h and 88h respectively. |
|||
; |
|||
; PIO ----ZP---- ----4P---- |
|||
; 0 DATA 0 90h DATA 0 B8h |
|||
; 0 DATA 1 91h DATA 1 B9h |
|||
; 0 CMD 0 92h CMD 0 BAh |
|||
; 0 CMD 1 93h CMD 1 BBh |
|||
; 1 DATA 0 94h DATA 0 BCh |
|||
; 1 DATA 1 95h DATA 1 BDh |
|||
; 1 CMD 0 96h CMD 0 BEh |
|||
; 1 CMD 1 97h CMD 1 BFh |
|||
; 2 DATA 0 C0h |
|||
; 2 DATA 1 C1h |
|||
; 2 CMD 0 C2h |
|||
; 2 CMD 1 C3h |
|||
; 3 DATA 0 C4h |
|||
; 3 DATA 1 C5h |
|||
; 3 CMD 0 C6h |
|||
; 3 CMD 1 C7h |
|||
; |
|||
PIODEBUG .EQU 1 |
|||
; |
|||
M_Output .EQU $00 << 6 |
|||
M_Input .EQU $01 << 6 |
|||
M_Bidir .EQU $02 << 6 |
|||
M_BitCtrl .EQU $03 << 6 |
|||
M_BitAllIn .EQU $FF |
|||
M_BitAllOut .EQU $00 |
|||
; |
|||
PIO_NONE .EQU 0 |
|||
PIO_ZPIO .EQU 1 |
|||
PIO_8255 .EQU 2 |
|||
PIO_PORT .EQU 3 |
|||
|
|||
; SET MAXIMUM NUMBER OF INTERRUPTS AVAILABLE FOR ALL |
|||
; ENSURE INTERRUPTS ARE NOT TURNED ON IF IM2 IS NOT SET. |
|||
|
|||
INT_ALLOC .DB 0 |
|||
INT_N .EQU 00000000B |
|||
#IF (INTMODE == 2) |
|||
INT_Y .EQU 00000100B |
|||
INT_ALLOW .EQU 4 |
|||
#ELSE |
|||
INT_Y .EQU INT_N |
|||
INT_ALLOW .EQU 0 |
|||
#ENDIF |
|||
; |
|||
INT0 .EQU 00000000B |
|||
INT1 .EQU 00000001B |
|||
INT2 .EQU 00000010B |
|||
INT3 .EQU 00000011B |
|||
|
|||
; |
|||
; SETUP THE DISPATCH TABLE ENTRIES |
|||
; |
|||
; PIO_CNT HOLDS THE NUMBER OF DEVICED CALCULATED FROM THE NUMBER OF DEFPIO MACROS |
|||
; PIO_CNT SHOULD INCREASE BY 2 FOR EVERY PIO CHIP ADDED. |
|||
; |
|||
; PIO_PREINIT WILL READ THROUGH ALL PIOCFG TABLES AND CONFIGURE EACH TABLE. |
|||
; IT WITH THEN CALL PIO_INITUNIT TO INITIALIZE EACH DEVICE TO ITS DEFAULT STATE |
|||
; |
|||
; EXPECTS NOTHING ON ENTRY |
|||
; |
|||
PIO_PREINIT: |
|||
CALL NEWLINE ;D |
|||
LD B,PIO_CNT ; LOOP CONTROL |
|||
LD C,0 ; PHYSICAL UNIT INDEX |
|||
XOR A ; ZERO TO ACCUM |
|||
; LD (PIO_DEV),A ; CURRENT DEVICE NUMBER |
|||
LD (INT_ALLOC),A ; START WITH NO INTERRUPTS ALLOCATED |
|||
PIO_PREINIT0: |
|||
PUSH BC ; SAVE LOOP CONTROL |
|||
; LD A,C ; INITIALIZE THE UNIT |
|||
|
|||
; PUSH AF ;D |
|||
; LD A,'u' ;D |
|||
; CALL COUT ;D |
|||
; POP AF ;D |
|||
; CALL PRTHEXBYTE ;D UNIT |
|||
; CALL PC_SPACE ;D |
|||
|
|||
; RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (32 BYTES) |
|||
; RLCA ; ... |
|||
; RLCA ; ... TO GET OFFSET INTO CFG TABLE |
|||
; RLCA |
|||
;; RLCA |
|||
; LD HL,PIO_CFG ; POINT TO START OF CFG TABLE |
|||
; PUSH AF |
|||
; CALL ADDHLA ; HL := ENTRY ADDRESS |
|||
; POP AF |
|||
; CALL ADDHLA ; HL := ENTRY ADDRESS |
|||
; PUSH HL ; SAVE IT |
|||
; POP IY ; ... TO IY |
|||
|
|||
CALL IDXCFG |
|||
|
|||
LD (HL),C |
|||
|
|||
PUSH AF ;D |
|||
LD A,'c' ;D |
|||
CALL COUT ;D |
|||
POP AF ;D |
|||
PUSH BC ;D |
|||
PUSH HL ;D |
|||
POP BC ;D |
|||
CALL PRTHEXWORD ;D CONFIG TABLE |
|||
CALL PC_SPACE ;D |
|||
POP BC ;D |
|||
|
|||
LD A,(IY+1) ; GET THE PIO TYPE DETECTED |
|||
CP PIO_PORT ; SET FLAGS |
|||
|
|||
PUSH AF ;D |
|||
LD A,'t' ;D |
|||
CALL COUT ;D |
|||
POP AF ;D |
|||
CALL PRTHEXBYTE ;D TYPE |
|||
CALL PC_SPACE ;D |
|||
|
|||
; JR Z,BADINIT |
|||
|
|||
; PUSH BC ; SAVE LOOP CONTROL |
|||
; LD BC,PIO_FNTBL ; BC := FUNCTION TABLE ADDRESS |
|||
; DEC A |
|||
; JR Z,TYPFND ; SKIP IT IF NOTHING FOUND |
|||
; LD BC,PPI_FNTBL ; BC := FUNCTION TABLE ADDRESS |
|||
; DEC A |
|||
; JR Z,TYPFND ; ADD ENTRY IF PIO FOUND, BC:DE |
|||
; LD BC,PRT_FNTBL |
|||
; DEC A |
|||
; JR Z,TYPFND |
|||
; POP BC |
|||
; JR BADINIT |
|||
|
|||
PUSH HL |
|||
LD DE,-1 ; INITIALIZE THIS DEVICE WITH |
|||
CALL PIO_INITDEV ; DEFAULT VALUES |
|||
POP HL |
|||
|
|||
; JR NZ,SKPINIT |
|||
|
|||
; AT THIS POINT WE KNOW WE |
|||
; HAVE A VALID DEVICE SO ADD IT |
|||
|
|||
LD A,8 ; CALCULATE THE FUNCTION TABLE |
|||
CALL ADDHLA ; POSITION WHICH FOLLOWS THE |
|||
PUSH HL ; CONFIGURATION TABLE OF EACH |
|||
POP BC ; DEVICE |
|||
|
|||
TYPFND: PUSH AF ;D |
|||
LD A,'f' ;D |
|||
CALL COUT ;D |
|||
POP AF ;D |
|||
PUSH BC ;D |
|||
CALL PRTHEXWORD ;D FUNCTION TABLE |
|||
POP BC ;D |
|||
CALL NEWLINE ;D |
|||
|
|||
PUSH IY ; ADD ENTRY IF PIO FOUND, BC:DE |
|||
POP DE ; BC: DRIVER FUNCTION TABLE |
|||
CALL CIO_ADDENT ; DE: ADDRESS OF UNIT INSTANCE DATA |
|||
|
|||
BADINIT:POP BC ; RESTORE LOOP CONTROL |
|||
|
|||
INC C ; NEXT PHYSICAL UNIT |
|||
SKPINIT:DJNZ PIO_PREINIT0 ; LOOP UNTIL DONE |
|||
|
|||
PUSH AF ;D |
|||
PRTS("INTS=$") ;D |
|||
LD A,(INT_ALLOC) ;D |
|||
CALL PRTHEXBYTE ;D |
|||
POP AF ;D |
|||
PUSH DE ;D |
|||
LD DE,CIO_TBL-3 ;D |
|||
CALL DUMP_BUFFER ;D |
|||
POP DE ;D |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET ; AND RETURN |
|||
; |
|||
; INDEX INTO THE CONFIG TABLE |
|||
; ON ENTRY C = UNIT NUMBER |
|||
; ON EXIT IY = CONFIG DATA POINTER |
|||
; ON EXIT DE = CONFIG TABLE START |
|||
; |
|||
; EACH CONFIG TABLE IS 24 BYTES LONG |
|||
; |
|||
CFG_SIZ .EQU 24 |
|||
; |
|||
IDXCFG: LD A,C |
|||
RLCA ; X 2 |
|||
RLCA ; X 4 |
|||
RLCA ; X 8 |
|||
LD H,0 |
|||
LD L,A ; HL = X 8 |
|||
PUSH HL |
|||
ADD HL,HL ; HL = X 16 |
|||
POP DE |
|||
ADD HL,DE ; HL = X 24 |
|||
LD DE,PIO_CFG |
|||
ADD HL,DE |
|||
PUSH HL ; COPY CFG DATA PTR |
|||
POP IY ; ... TO IY |
|||
RET |
|||
|
|||
; PIO_INITDEV - INITIALIZE DEVICE |
|||
; |
|||
; IF DE = FFFF THEN THE SETUP PARAMETER WORD WILL BE READ FROM THE DEVICE CONFIGURATION |
|||
; TABLE POINTED TO BY IY AND THE PIO PORT WILL BE PROGRAMMED BASED ON THAT CONFIGURATION. |
|||
; |
|||
; OTHERWISE THE PIO PORT WILL BE PROGRAMMED BY THE SETUP PARAMETER WORD IN DE AND THIS |
|||
; WILL BE SAVED IN THE DEVICE CONFIGURATION TABLE POINTED TO BY IY. |
|||
; |
|||
; ALL OTHER CONFIGURATION OF THE DEVICE CONFIGURATION TABLE IS DONE UPSTEAM BY PIO_PREINIT |
|||
|
|||
PIO_INITDEV: |
|||
; TEST FOR -1 (FFFF) WHICH MEANS USE CURRENT CONFIG (JUST REINIT) |
|||
LD A,D ; TEST DE FOR |
|||
AND E ; ... VALUE OF -1 |
|||
INC A ; ... SO Z SET IF -1 |
|||
JR NZ,PIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG |
|||
PIO_INITDEV0: |
|||
; LOAD EXISTING CONFIG (DCW) TO REINIT |
|||
LD E,(IY+4) ; LOW BYTE |
|||
LD D,(IY+5) ; HIGH BYTE |
|||
; |
|||
PIO_INITDEV1: ; WHICH DEVICE TYPE? |
|||
LD A,(IY+1) |
|||
CP PIO_ZPIO |
|||
JR Z,SETPIO0 |
|||
CP PIO_8255 |
|||
JP Z,SET_8255 |
|||
CP PIO_PORT |
|||
JP Z,SET_PORT |
|||
BAD_SET:OR $FF ; UNKNOWN DEVICE |
|||
RET |
|||
|
|||
SETPIO0:LD A,E ; GET MODE |
|||
AND 11000000B ; BITS (B7B6) |
|||
CP 10000000B ; IS IT BIDIR? |
|||
JR NZ,SETPIO1 |
|||
LD A,(IY+2) ; GET CHANNEL |
|||
OR A |
|||
JR NZ,BAD_SET ; CAN'T DO ON CH1 |
|||
|
|||
; VALIDATE INTERRUPT REQUEST |
|||
; GRANT INTERRUPT IF THERE IS A FREE INTERRUPT |
|||
; GRANT INTERRUPT IF AN INTERRUPT IS ALREADY ALLOCATED TO THIS UNIT |
|||
|
|||
SETPIO1:PUSH AF ;D |
|||
LD A,'[' ;D |
|||
CALL COUT ;D |
|||
LD A,(IY) ;D |
|||
CALL PRTHEXBYTE ;D |
|||
LD A,']' ;D |
|||
CALL COUT ;D |
|||
POP AF ;D |
|||
|
|||
BIT 2,E ; SKIP IF WE ARE NOT REQUESTING |
|||
JP Z,SETPIO2 ; AN INTERRUPT |
|||
|
|||
PRTS("[INTREQ]$") ;D |
|||
|
|||
; LD A,(IY+4) ; GET CURRENT INTERRUPT SETTING |
|||
; BIT 2,A ; SKIP IF IT IS ALREADY |
|||
; JP NZ,SETPIO2 ; ALLOCATED TO THIS UNIT |
|||
|
|||
LD A,(INT_ALLOC) ; WE NEED TO ALLOCATE AN |
|||
CP INT_ALLOW ; INTERRUPT. DO WE HAVE |
|||
JR NC,BAD_SET ; ONE FREE? |
|||
|
|||
PRTS("[ALLOCINT]$") ;D |
|||
|
|||
; WHICH INTERRUPT IS FREE ? |
|||
; SCAN THROUGH THE CFG TABLES |
|||
; AND FIND A FREE ONE |
|||
|
|||
PUSH AF ; NESTED LOOP |
|||
LD DE,CFG_SIZ ; OUTSIDE LOOP IS INTERRUPT |
|||
LD B,INT_ALLOW ; INSIDE LOOP IS DEVICE |
|||
SETPIOP: LD C,B |
|||
DEC C |
|||
PUSH BC |
|||
LD B,PIO_CNT |
|||
LD HL,PIO_CFG+4 |
|||
SETPIOX: LD A,(HL) |
|||
BIT 2,A ; JUMP TO NEXT DEVICE |
|||
JR Z,SETPIOY ; IF NO INTERRUPT ON |
|||
AND 00000011B ; THIS DEVICE |
|||
|
|||
CP C ; IF WE MATCH AN INTERRUPT HERE THEN IT IS NOT FREE. |
|||
JR NZ,SETPIOY ; SO EXIT INSIDE LOOP AND TRY NEXT INTERRUPT |
|||
|
|||
XOR A ; WE MATCH INT 0 - IF WE ARE CHECKING FOR IT THEN |
|||
OR C ; WE REGARD IS AS FREE. |
|||
JR NZ,SETPIOZ |
|||
|
|||
SETPIOY: ADD HL,DE |
|||
DJNZ SETPIOX |
|||
|
|||
JR SETPIOQ ; WE GET HERE IF THE CURRENT INTERRUPT |
|||
; WAS NOT MATCHED SO IT IS FREE |
|||
SETPIOZ: POP BC |
|||
DJNZ SETPIOP |
|||
POP AF |
|||
|
|||
PRTS("[NONEFREE]$") |
|||
RET |
|||
|
|||
SETPIOQ:PUSH AF ; AVAILABLE INTERRUPT IS IN C |
|||
PRTS("[FREE]=$") |
|||
LD A,C |
|||
CALL PRTHEXBYTE |
|||
POP AF |
|||
|
|||
POP AF |
|||
POP AF |
|||
|
|||
SETPIOR:LD HL,INT_ALLOC ; INCREASE THE COUNT |
|||
INC (HL) ; OF USED INTERRUPTS |
|||
LD A,(HL) |
|||
|
|||
; LD A,(IY) ; IS THIS UNIT |
|||
; INC A ; UNITIALIZED? |
|||
; JR Z,SETPIO6 |
|||
|
|||
LD A,(IY+4) ; IT IS UNITIALIZED SO |
|||
OR C ; SAVE THE ALLOCATES |
|||
LD (IY+4),A ; INTERRUPT |
|||
; |
|||
; FOR THIS DEVICE AND INTERRUPT, UPDATE THE CONFIG TABLE FOR THIS DEVICE. |
|||
; PIO_IN, PIO_OUT, PIO_IST, PIO_OST ENTRIES NEED TO BE REDIRECTED. |
|||
; INTERRUPT VECTOR NEEDS TO BE UPDATED |
|||
; |
|||
LD A,(IY+0) |
|||
LD HL,0 |
|||
; SETUP PIO INTERRUPT VECTOR IN IVT |
|||
LD HL,HBX_IV09+1 |
|||
|
|||
; CALL SPK_BEEP |
|||
; |
|||
SETPIO6:RET |
|||
|
|||
; EXIT WITH FREE INTERRUPT IN C |
|||
|
|||
LD A,C |
|||
LD (INT_ALLOC),A |
|||
|
|||
LD A,E |
|||
AND 11000000B |
|||
OR 00000100B |
|||
OR C |
|||
LD E,A |
|||
LD (IY+5),A |
|||
; |
|||
; TODO: DEALLOCATE AN INTERRUPT |
|||
; |
|||
; LD A,(INT_ALLOC) |
|||
; DEC A |
|||
; LD (INT_ALLOC),A |
|||
; |
|||
SETPIO2: |
|||
|
|||
; DE CONTAINS THE MODE IF INTERRUPT ROUTINE SKIPPED |
|||
|
|||
PRTS("[NOINTREQ]$") ;D |
|||
|
|||
; LD A,(IY+4) |
|||
LD A,E ; GET MODE AND CREATE COMMAND |
|||
AND 11000000B ; $B0 |
|||
OR 00001111B ; $0F |
|||
|
|||
LD C,(IY+3) ; GET DATA PORT |
|||
INC C ; POINT TO CMD |
|||
INC C ; PORT |
|||
OUT (C),A ; SET MODE |
|||
CP (M_BitCtrl | $0F) ; IF MODE 3 |
|||
JR NZ,SETPIO3 |
|||
LD A,(IY+5) ; SET I/O DIRECTION |
|||
OUT (C),A ; FOR MODE 3 |
|||
|
|||
SETPIO3:; INTERUPT HANDLING |
|||
|
|||
JP SETPIO4 |
|||
|
|||
; SETUP THE INTERRUPT VECTOR |
|||
|
|||
LD A,E |
|||
AND 00000011B |
|||
; DEC A ; INDEX INTO THE |
|||
ADD A,A ; THE VECTOR TABLE |
|||
ADD A,A ; |
|||
LD C,A |
|||
LD B,0 |
|||
LD HL,HBX_IV09+1 |
|||
ADD HL,BC ; GET THE ADDRESS OF |
|||
PUSH DE |
|||
LD D,(HL) ; THAT INTERRUPT |
|||
INC HL ; HANDLER |
|||
LD E,(HL) |
|||
LD HL,0 ;HBX_IVT+IVT_PIO0 ; POPULATE THE |
|||
LD A,L ; GET LOW BYTE OF IVT ADDRESS |
|||
ADD HL,BC ; INTERRUPT TABLE |
|||
LD (HL),D ; WITH THE INTERRUPT |
|||
INC HL ; HANDLER ADDRESS FOR |
|||
LD (HL),E ; THIS UNIT |
|||
POP DE |
|||
LD HL,INT_ALLOC |
|||
LD C,(HL) |
|||
LD B,0 |
|||
LD HL,PRTTAB-1 ; SAVE THE DATA |
|||
ADD HL,BC ; PORT FOR EACH INTERRUPT |
|||
LD C,(IY+3) |
|||
LD (HL),C |
|||
|
|||
INC C ; POINT TO CMD PORT |
|||
INC C |
|||
DI ; SET THE VECTOR ADDRESS |
|||
OUT (C),A |
|||
|
|||
; LD A,10000011B ; ENABLE INTERRUPTS ON |
|||
OUT (C),A ; THIS UNIT |
|||
EI |
|||
; JR GUD_SET |
|||
; |
|||
SETPIO4:LD A,00000111B ; $07 |
|||
OUT (C),A ; NO INTERRUPTS |
|||
; |
|||
; SUCCESSFULL SO SAVE DEVICE CONFIGURATION WORD (DCW) |
|||
; |
|||
GUD_SET:LD (IY+4),E ; LOW BYTE |
|||
LD (IY+5),D ; HIGH BYTE |
|||
; |
|||
; UPDATE THE DEVICE TABLE WITH THE ADDRESSES FOR THE CORRECT ROUTINE. |
|||
; |
|||
LD A,E |
|||
AND 00000111B |
|||
LD HL,INTMATRIX ; POINT TO EITHER THE INTERRUPT |
|||
JR NZ, USEIM |
|||
LD HL,POLMATRIX ; MATRIX OR THE POLLED MATRIX |
|||
USEIM: PUSH HL |
|||
|
|||
PUSH IY ; CALCULATE THE DESTINATION |
|||
POP HL ; ADDRESS IN THE PIO_CFG TABLE |
|||
LD BC,8 ; FOR THE FOUR ADDESSES TO BE |
|||
ADD HL,BC ; COPIED TO |
|||
|
|||
; LD B,0 ; 00000000 CALCULATE THE SOURCE ADDRESS |
|||
LD C,E ; XX?????? FROM THE MATRIX. EACH ENTRY |
|||
SRL C ; 0XX????? IN THE MATRIX IS 8 BYTES SO |
|||
SRL C ; 00XX???? SOURCE = MATRIX BASE + (8 * MODE) |
|||
SRL C ; 000XX??? |
|||
POP DE ; LOAD THE MATRIX BASE |
|||
; LD DE,POLMATRIX |
|||
EX DE,HL |
|||
ADD HL,BC ; HL = SOURCE |
|||
|
|||
LD C,8 ; COPY 8 BYTES |
|||
LDIR |
|||
|
|||
; PUSH IY |
|||
; POP DE |
|||
; CALL DUMP_BUFFER |
|||
|
|||
XOR A |
|||
RET |
|||
|
|||
PRTTAB: .DB 0 |
|||
.DB 0 |
|||
.DB 0 |
|||
.DB 0 |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; INPUT INTERRUPT VECTOR MACRO AND DEFINITION FOR FOUR PORTS |
|||
; |
|||
#DEFINE PIOMIVT(PIOIN,PIOIST,PIOPRT) \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; RETURN WITH ERROR IF THERE IS \ |
|||
#DEFCONT ; ALREADY A CHARACTER IN BUFFER \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; OTHERWISE CHANGE THE STATUS TO \ |
|||
#DEFCONT ; SHOW THERE IS ONE CHARACTER IN \ |
|||
#DEFCONT ; THE BUFFER AND READ IT IN AND \ |
|||
#DEFCONT ; AND STORE IT.RETURN GOOD STATUS.\ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \ LD A,(_CIST) |
|||
#DEFCONT \ OR A |
|||
#DEFCONT \ JR NZ,_OVFL |
|||
#DEFCONT \ LD A,(PIOPRT) |
|||
#DEFCONT \ LD C,A |
|||
#DEFCONT \ LD A,1 |
|||
#DEFCONT \ LD (_CIST),A |
|||
#DEFCONT \ IN A,(C) |
|||
#DEFCONT \ LD (_CICH),A |
|||
#DEFCONT \ OR $FF |
|||
#DEFCONT \ RET |
|||
#DEFCONT \_OVFL:XOR A |
|||
#DEFCONT \ RET |
|||
#DEFCONT ;\ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \PIOIN:CALL PIOIST |
|||
#DEFCONT \ JR Z,PIOIN |
|||
#DEFCONT \ LD A,(_CICH) |
|||
#DEFCONT \ LD E,A |
|||
#DEFCONT \ XOR A |
|||
#DEFCONT \ LD (_CIST),A |
|||
#DEFCONT \ RET |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; If THERE A CHARACTER \ |
|||
#DEFCONT ; AVAILABLE? RETURN NUMBER \ |
|||
#DEFCONT ; IN A - 0 OR 1 \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \PIOIST:LD A,(_CIST) |
|||
#DEFCONT \ AND 00000001B |
|||
#DEFCONT \ RET |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; CIST : 01 = CHARACTER READY ELSE NOT READY \ |
|||
#DEFCONT ; CISH : CHARACTER STORED BY INTERRUPT \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \_CIST .DB 00 |
|||
#DEFCONT \_CICH .DB 00 |
|||
; |
|||
PIOIVT0:.MODULE PIOIVT0 |
|||
PIOMIVT(PIO0IN,PI0_IST,PRTTAB+0) |
|||
PIOIVT1:.MODULE PIOIVT1 |
|||
PIOMIVT(PIO1IN,PI1_IST,PRTTAB+1) |
|||
PIOIVT2:.MODULE PIOIVT2 |
|||
PIOMIVT(PIO2IN,PI2_IST,PRTTAB+2) |
|||
PIOIVT3:.MODULE PIOIVT3 |
|||
PIOMIVT(PIO3IN,PI3_IST,PRTTAB+3) |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; OUTPUT INTERRUPT VECTOR MACRO AND DEFINITION FOR FOUR PORTS |
|||
; |
|||
; AN INTERRUPT IS GENERATED WHEN THE RECEIVING DEVICE CAN ACCEPT A CHARACTER |
|||
; |
|||
#DEFINE PIOMOVT(PIOOUT,PIOOST,PIOPRT) \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; RETURN IF WE ARE WAITING FOR A \ |
|||
#DEFCONT ; CHARACTER (COST = 00) \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; IF ZERO CHARACTERS READY |
|||
#DEFCONT ; (COST = 01) CHANGE STATUS TO \ |
|||
#DEFCONT ; WAITING FOR CHARACTER (COST 00) \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; IF A CHARACTER IS READY THEN \ |
|||
#DEFCONT ; OUTPUT AND CHANGE STATUS TO \ |
|||
#DEFCONT ; ZERO CHARACTERS READY \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \ LD A,(_COST) |
|||
#DEFCONT \ DEC A |
|||
#DEFCONT \ RET M |
|||
#DEFCONT \ JR Z,_WFC |
|||
#DEFCONT \ LD A,(_COCH) |
|||
#DEFCONT \ LD E,A |
|||
#DEFCONT \_ONOW:LD A,(PIOPRT) |
|||
#DEFCONT \ LD C,A |
|||
#DEFCONT \ OUT (C),E |
|||
#DEFCONT \ LD A,1 |
|||
#DEFCONT \_WFC: LD (_COST),A |
|||
#DEFCONT \ RET |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; WAIT FOR SPACE FOR THE CHARACTER\ |
|||
#DEFCONT ; IF WE ARE WAITING FOR A \ |
|||
#DEFCONT ; CHARACTRE THEN OUTPUT IT NOW \ |
|||
#DEFCONT ; OTHERWISE STORE IT UNTIL THE \ |
|||
#DEFCONT ; INTERRUPT CALLS FOR IT \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \PIOOUT:LD A,(_COST) |
|||
#DEFCONT \ CP 2 |
|||
#DEFCONT \ JR C,_ONOW |
|||
#DEFCONT \ LD A,E |
|||
#DEFCONT \ LD (_COCH),A |
|||
#DEFCONT \ LD A,2 |
|||
#DEFCONT \ LD (_COST),A |
|||
#DEFCONT \ JR PIOOUT |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; RETURN WITH NUMBER OF \ |
|||
#DEFCONT ; CHARACTERS AVAILABLE 0 or 1 \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \PIOOST:LD A,(_COST) |
|||
#DEFCONT \ DEC A |
|||
#DEFCONT \ DEC A |
|||
#DEFCONT \ RET Z |
|||
#DEFCONT \ LD A,1 |
|||
#DEFCONT \ RET |
|||
#DEFCONT ;\ |
|||
#DEFCONT ; COST : 00 WAITING FOR CHARACTER\ |
|||
#DEFCONT ; 01 ZERO CHARACTERS READY\ |
|||
#DEFCONT ; 02 ONE CHARACTER READY \ |
|||
#DEFCONT ; COCH : CHARACTER TO OUTPUT \ |
|||
#DEFCONT ;\ |
|||
#DEFCONT \_COST .DB 01 |
|||
#DEFCONT \_COCH .DB 00 |
|||
; |
|||
PIOOVT0:.MODULE PIOOVT0 |
|||
PIOMOVT(PIO0OUT,PI0_OST,PRTTAB+0) |
|||
PIOOVT1:.MODULE PIOOVT1 |
|||
PIOMOVT(PIO1OUT,PI1_OST,PRTTAB+1) |
|||
PIOOVT2:.MODULE PIOOVT2 |
|||
PIOMOVT(PIO2OUT,PI2_OST,PRTTAB+2) |
|||
PIOOVT3:.MODULE PIOOVT3 |
|||
PIOMOVT(PIO3OUT,PI3_OST,PRTTAB+3) |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; NON INTERRUPT OUTPUT ROUTINE - SHARED |
|||
; |
|||
; INPUT WILL ALWAYS RETURN ERROR, CHARACTER RETURNED IS UNDEFINED. |
|||
; OUTPUT WILL ALWAYS RETURN SUCCESS |
|||
; INPUT-STATUS WILL ALWAYS RETURN 0 CHARACTERS IN BUFFER. |
|||
; OUTPUT-STATUS WILL ALWAYS RETURN 1 CHARACTER SPACE IN BUFFER. |
|||
|
|||
PIOSHO_IN: |
|||
LD A,1 |
|||
RET |
|||
; |
|||
PIOSHO_OUT: |
|||
LD C,(IY+3) |
|||
OUT (C),E |
|||
XOR A |
|||
RET |
|||
; |
|||
PIOSHO_IST: XOR A |
|||
RET |
|||
; |
|||
PIOSH_OST: |
|||
LD A,1 |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; NON INTERRUPT INPUT ROUTINE - SHARED |
|||
; |
|||
; INPUT WILL ALWAYS A CHARACTER AND SUCCESS. |
|||
; OUTPUT WILL ALWAYS RETURN FAILURE |
|||
; INPUT STATUS WILL ALWAYS RETURN 1 CHARACTER IN BUFFER. |
|||
;OUTPUT-STATUS WILL ALWAYS RETURN 0 CHARACTER SPACE IN BUFFER. |
|||
; |
|||
PIOSHI_IN: |
|||
LD C,(IY+3) |
|||
IN A,(C) |
|||
LD E,A |
|||
XOR A |
|||
RET |
|||
; |
|||
PIOSHI_OUT: |
|||
LD A,1 |
|||
RET |
|||
; |
|||
PIOSH_IST: |
|||
LD A,1 |
|||
RET |
|||
; |
|||
PIOSHI_OST: |
|||
XOR A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; ON ENTRY IY POINTS TO THE DEVICE RECORD. GET AND RETURN THE CONFIGURATION WORD IN DE |
|||
; |
|||
PIO_QUERY: |
|||
PPI_QUERY: |
|||
LD E,(IY+4) ; FIRST CONFIG BYTE TO E |
|||
LD D,(IY+5) ; SECOND CONFIG BYTE TO D |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; ON ENTRY IY POINTS TO THE DEVICE RECORD. FOR CHARACTER DEVICES BIT 6 OF ATTRIBUTE |
|||
; INDICATES PARALLEL PORT IF 1 SO WE SET IT. COMMON TO ALL PORTS |
|||
; |
|||
PIO_DEVICE: |
|||
PPI_DEVICE: |
|||
LD D,CIODEV_PIO ; D := DEVICE TYPE |
|||
LD E,(IY) ; E := PHYSICAL UNIT |
|||
LD C,$40 ; C := ATTRIBUTE |
|||
LD H,0 ; H := 0, DRIVER HAS NO MODES |
|||
LD L,(IY+3) ; L := BASE I/O ADDRESS |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET |
|||
; |
|||
INTMATRIX: |
|||
.DW PIO0IN, PIO0OUT, PI0_IST, PI0_OST |
|||
.DW PIO1IN, PIO1OUT, PI1_IST, PI1_OST |
|||
.DW PIO2IN, PIO2OUT, PI2_IST, PI2_OST |
|||
.DW PIO3IN, PIO3OUT, PI3_IST, PI3_OST |
|||
POLMATRIX: |
|||
.DW PIOSHO_IN, PIOSHO_OUT, PIOSHO_IST, PIOSH_OST ; OUTPUT |
|||
.DW PIOSHI_IN, PIOSHI_OUT, PIOSH_IST, PIOSHI_OST ; INPUT |
|||
.DW 0,0,0,0 ; BIDIR |
|||
.DW 0,0,0,0 ; BIT MODE |
|||
|
|||
SET_8255: |
|||
RET |
|||
; |
|||
SET_BYE: |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET |
|||
; |
|||
; ------------------------------------ |
|||
; i8255 FUNCTION TABLE ROUTINES |
|||
;------------------------------------- |
|||
|
|||
PPI_IN: |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET |
|||
; |
|||
PPI_OUT: |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET |
|||
; |
|||
PPI_IST: |
|||
RET |
|||
; |
|||
PPI_OST: |
|||
RET |
|||
; |
|||
; PIO_INITDEV - Configure device. |
|||
; If DE = FFFF then extract the configuration information from the table of devices and program the device using those settings. |
|||
; Otherwise use the configuration information in DE to program those settings and save them in the device table |
|||
|
|||
PPI_INITDEV: |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET |
|||
PPI_INT:OR $FF ; NZ SET TO INDICATE INT HANDLED |
|||
RET |
|||
; |
|||
PIO_PRTCFG: |
|||
; ANNOUNCE PORT |
|||
CALL NEWLINE ; FORMATTING |
|||
PRTS("PIO$") ; FORMATTING |
|||
LD A,(IY) ; DEVICE NUM |
|||
CALL PRTDECB ; PRINT DEVICE NUM |
|||
PRTS(": IO=0x$") ; FORMATTING |
|||
LD A,(IY+3) ; GET BASE PORT |
|||
CALL PRTHEXBYTE ; PRINT BASE PORT |
|||
; |
|||
; PRINT THE PIO TYPE |
|||
CALL PC_SPACE ; FORMATTING |
|||
LD A,(IY+1) ; GET PIO TYPE BYTE |
|||
LD DE,PIO_TYPE_STR ; POINT HL TO TYPE MAP TABLE |
|||
CALL PRTIDXDEA |
|||
|
|||
; ALL DONE IF NO PIO WAS DETECTED |
|||
LD A,(IY+1) ; GET PIO TYPE BYTE |
|||
OR A ; SET FLAGS |
|||
RET Z ; IF ZERO, NOT PRESENT |
|||
; |
|||
PRTS(" MODE=$") ; FORMATTING |
|||
LD E,(IY+4) ; LOAD CONFIG |
|||
LD D,(IY+5) ; ... WORD TO DE |
|||
CALL PS_PRTPC0 ; PRINT CONFIG |
|||
; |
|||
LD A,(IY+4) ; PRINT |
|||
BIT 2,A ; ALLOCATED |
|||
JR Z,NOINT ; INTERRUPT |
|||
PRTS("/i$") |
|||
LD A,(IY+4) |
|||
AND 00000011B |
|||
CALL PRTDECB |
|||
NOINT: XOR A |
|||
RET |
|||
; |
|||
; WORKING VARIABLES |
|||
; |
|||
PIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT |
|||
; |
|||
; DESCRIPTION OF DIFFERENT PORT TYPES |
|||
; |
|||
PIO_TYPE_STR: |
|||
.TEXT "<NOT PRESENT>$" ; IDX 0 |
|||
.TEXT "Zilog PIO$" ; IDX 1 |
|||
.TEXT "i8255 PPI$" ; IDX 2 |
|||
.TEXT "IO Port$" ; IDX 3 |
|||
; |
|||
; Z80 PIO PORT TABLE - EACH ENTRY IS FOR 1 CHIP I.E. TWO PORTS |
|||
; |
|||
; 32 BYTE DATA STRUCTURE FOR EACH PORT |
|||
; |
|||
; .DB 0 ; IY+0 CIO DEVICE NUMBER (SET DURING PRE-INIT, THEN FIXED) |
|||
; .DB 0 ; IY+1 PIO TYPE (SET AT ASSEMBLY, FIXED) |
|||
; .DB 0 ; IY+2 PIO CHANNEL (SET AT ASSEMBLY, FIXED) |
|||
; .DB PIOBASE+2 ; IY+3 BASE DATA PORT (SET AT ASSEMBLY, FIXED) |
|||
; .DB 0 ; IY+4 SPW - MODE 3 I/O DIRECTION BYTE (SET AT ASSEMBLE, SET WITH INIT) |
|||
; .DB 0 ; IY+5 SPW - MODE, INTERRUPT (SET AT ASSEMBLY, SET WITH INIT) |
|||
; .DW 0 ; IY+6/7 FUNCTION TABLE (SET AT ASSEMBLY, SET DURING PRE-INIT AND AT INIT) |
|||
; .DW PIO_IN ; IY+8 ADDR FOR DEVICE INPUT (SET WITH INIT) |
|||
; .DW PIO_OUT ; IY+10 ADDR FOR DEVICE OUTPUT (SET WITH INIT) |
|||
; .DW PIO_IST ; IY+12 ADDR FOR DEVICE INPUT STATUS (SET WITH INIT) |
|||
; .DW PIO_OST ; IY+14 ADDR FOR DEVICE OUTPUT STATUS (SET WITH INIT) |
|||
; .DW PIO_INITDEV ; IY+16 ADDR FOR INITIALIZE DEVICE ROUTINE (SET AT ASSEMBLY, FIXED) |
|||
; .DW PIO_QUERY ; IY+18 ADDR FOR QUERY DEVICE RECORD ROUTINE (SET AT ASSEMBLY, FIXED) |
|||
; .DW PIO_DEVICE ; IY+20 ADDR FOR DEVICE TYPE ROUTINE (SET AT ASSEMBLY, FIXED) |
|||
; .FILL 10 |
|||
; |
|||
; SETUP PARAMETER WORD: |
|||
; |
|||
; +-------------------------------+ +-------+-----------+---+-------+ |
|||
; | BIT CONTROL | | MODE | | A | INT | |
|||
; +-------------------------------+ --------------------+-----------+ |
|||
; F E D C B A 9 8 7 6 5 4 3 2 1 0 |
|||
; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- |
|||
; |
|||
; |
|||
; MSB = BIT CONTROL MAP USE IN MODE 3 |
|||
; |
|||
; MODE B7 B6 = 00 Mode 0 Output |
|||
; 01 Mode 1 Input |
|||
; 10 Mode 2 Bidir |
|||
; 11 Mode 3 Bit Mode |
|||
; |
|||
; INTERRUPT ALLOCATED B2 = 0 NOT ALLOCATED |
|||
; = 1 IS ALLOCATED |
|||
; |
|||
; WHICH IVT IS ALLOCATES B1 B0 00 IVT_PIO0 |
|||
; 01 IVT_PIO1 |
|||
; 10 IVT_PIO2 |
|||
; 11 IVT_PIO3 |
|||
; |
|||
#DEFINE DEFPIO(MPIOBASE,MPIOCH0,MPIOCH1,MPIOCH0X,MPIOCH1X,MPIOIN0,MPIOIN1) \ |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB PIO_ZPIO |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB MPIOBASE |
|||
#DEFCONT \ .DB (MPIOCH0|MPIOIN0) |
|||
#DEFCONT \ .DB MPIOCH0X |
|||
#DEFCONT \ .DW 0 |
|||
#DEFCONT \ .DW 0,0,0,0, PIO_INITDEV,PIO_QUERY,PIO_DEVICE |
|||
#DEFCONT \ .FILL 2 |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB PIO_ZPIO |
|||
#DEFCONT \ .DB 1 |
|||
#DEFCONT \ .DB MPIOBASE+1 |
|||
#DEFCONT \ .DB (MPIOCH1|MPIOIN1) |
|||
#DEFCONT \ .DB MPIOCH1X |
|||
#DEFCONT \ .DW 0 |
|||
#DEFCONT \ .DW 0,0,0,0, PIO_INITDEV,PIO_QUERY,PIO_DEVICE |
|||
#DEFCONT \ .FILL 2 |
|||
; |
|||
; i8255 PORT TABLE - EACH ENTRY IS FOR 1 CHIP I.E. THREE PORTS |
|||
; |
|||
#DEFINE DEFPPI(MPPIBASE,MPPICH1,MPPICH2,MPPICH3,MPPICH1X,MPPICH2X,MPPICH3X) \ |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB PIO_8255 |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB MPPIBASE |
|||
#DEFCONT \ .DB (MPPICH1|00001000B) |
|||
#DEFCONT \ .DB MPPICH1X |
|||
#DEFCONT \ .DW 0 |
|||
#DEFCONT \ .DW PPI_IN,PPI_OUT,PPI_IST,PPI_OST,PPI_INITDEV,PPI_QUERY,PPI_DEVICE |
|||
#DEFCONT \ .FILL 2 |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB PIO_8255 |
|||
#DEFCONT \ .DB 1 |
|||
#DEFCONT \ .DB MPPIBASE+2 |
|||
#DEFCONT \ .DB (MPPICH2|00010000B) |
|||
#DEFCONT \ .DB MPPICH2X |
|||
#DEFCONT \ .DW 0 |
|||
#DEFCONT \ .DW PPI_IN,PPI_OUT,PPI_IST,PPI_OST,PPI_INITDEV,PPI_QUERY,PPI_DEVICE |
|||
#DEFCONT \ .FILL 2 |
|||
#DEFCONT \ .DB 0 |
|||
#DEFCONT \ .DB PIO_8255 |
|||
#DEFCONT \ .DB 2 |
|||
#DEFCONT \ .DB MPPIBASE+4 |
|||
#DEFCONT \ .DB (MPPICH3|00100000B) |
|||
#DEFCONT \ .DB MPPICH3X |
|||
#DEFCONT \ .DW 0 |
|||
#DEFCONT \ .DW PPI_IN,PPI_OUT,PPI_IST,PPI_OST,PPI_INITDEV,PPI_QUERY,PPI_DEVICE |
|||
#DEFCONT \ .FILL 2 |
|||
; |
|||
; HERE WE ACTUALLY DEFINE THE HARDWARE THAT THE HBIOS CAN ACCESS |
|||
; THE INIT ROUTINES READ AND SET THE INITIAL MODES FROM THIS INFO |
|||
; |
|||
PIO_CFG: |
|||
; |
|||
#IF PIO_4P |
|||
DEFPIO(PIO4BASE+0,M_Output,M_Input,M_BitAllOut,M_BitAllOut,INT_N,INT_N) |
|||
DEFPIO(PIO4BASE+4,M_Input,M_Input,M_BitAllOut,M_BitAllOut,INT_N,INT_N) |
|||
DEFPIO(PIO4BASE+8,M_Output,M_Output,M_BitAllOut,M_BitAllOut,INT_N,INT_N) |
|||
DEFPIO(PIO4BASE+12,M_Output,M_Output,M_BitAllOut,M_Output,INT_N,INT_N) |
|||
#ENDIF |
|||
#IF PIO_ZP |
|||
DEFPIO(PIOZBASE+0,M_Input,M_Input,M_BitAllOut,M_BitAllOut,INT_N,INT_N) |
|||
DEFPIO(PIOZBASE+4,M_Output,M_Output,M_BitAllOut,M_BitAllOut,INT_N,INT_N) |
|||
#ENDIF |
|||
; PIO_SBC & (PLATFORM == PLT_SBC) & (PPIDEMODE != PPIDEMODE_SBC)) |
|||
|
|||
#IF PIO_SBC |
|||
DEFPPI(PIOSBASE,M_Output,M_Output,M_Output,M_BitAllOut,M_BitAllOut,M_BitAllOut) |
|||
#ENDIF |
|||
; |
|||
PIO_CNT .EQU ($ - PIO_CFG) / CFG_SIZ |
|||
; |
|||
;------------------------------------------------------------------- |
|||
; WHEN WE GET HERE IY POINTS TO THE PIO_CFG TABLE WE ARE WORKING ON. |
|||
; C IS THE UNIT NUMBER |
|||
;------------------------------------------------------------------- |
|||
; |
|||
;PIO_INITUNIT: |
|||
; LD A,C ; SET THE UNIT NUMBER |
|||
; LD (IY),A |
|||
; |
|||
; LD DE,-1 ; LEAVE CONFIG ALONE |
|||
; CALL PIO_INITDEV ; IMPLEMENT IT AND RETURN |
|||
; XOR A ; SIGNAL SUCCESS |
|||
; RET ; AND RETURN |
|||
; |
|||
PIO_INIT: |
|||
; CALL SPK_BEEP |
|||
LD B,PIO_CNT ; COUNT OF POSSIBLE PIO UNITS |
|||
LD C,0 ; INDEX INTO PIO CONFIG TABLE |
|||
PIO_INIT1: |
|||
PUSH BC ; SAVE LOOP CONTROL |
|||
|
|||
; LD A,C ; PHYSICAL UNIT TO A |
|||
; RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (32 BYTES) |
|||
; RLCA ; ... |
|||
; RLCA ; ... TO GET OFFSET INTO CFG TABLE |
|||
; RLCA |
|||
;; RLCA |
|||
; LD HL,PIO_CFG ; POINT TO START OF CFG TABLE |
|||
; PUSH AF |
|||
; CALL ADDHLA ; HL := ENTRY ADDRESS |
|||
; POP AF |
|||
; CALL ADDHLA ; HL := ENTRY ADDRESS |
|||
; PUSH HL ; COPY CFG DATA PTR |
|||
; POP IY ; ... TO IY |
|||
; POP IY ; ... TO IY |
|||
|
|||
CALL IDXCFG |
|||
|
|||
LD A,(IY+1) ; GET PIO TYPE |
|||
OR A ; SET FLAGS |
|||
CALL NZ,PIO_PRTCFG ; PRINT IF NOT ZERO |
|||
|
|||
; PUSH DE |
|||
; LD DE,$FFFF ; INITIALIZE DEVICE/CHANNEL |
|||
; CALL PIO_INITDEV ; BASED ON DPW |
|||
; POP DE |
|||
|
|||
POP BC ; RESTORE LOOP CONTROL |
|||
INC C ; NEXT UNIT |
|||
DJNZ PIO_INIT1 ; LOOP TILL DONE |
|||
; |
|||
XOR A ; SIGNAL SUCCESS |
|||
RET ; DONE |
|||
; |
|||
SET_PORT: |
|||
; DEVICE TYPE IS I/O PORT SO JUST WRITE $00 TO IT |
|||
LD C,(IY+3) |
|||
OUT (C),A |
|||
XOR A |
|||
RET |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue