Browse Source

First iteration of ANSI driver

Refactored PPIDE driver for performance
import/raw
wayne 13 years ago
parent
commit
fd377a9f73
  1. 606
      branches/wbw/Source/ansi.asm
  2. 2
      branches/wbw/Source/config_n8vem_cvdu.asm
  3. 35
      branches/wbw/Source/cvdu.asm
  4. 367
      branches/wbw/Source/ppide.asm
  5. 169
      branches/wbw/Source/std.asm

606
branches/wbw/Source/ansi.asm

@ -1,181 +1,16 @@
; ansi.asm 12/3/2012 dwg - changed polarity of conditional jump for normal processing
; Status: Still very experimental, either doesn't work or is buggy
; WBW: BOGUS EQUATE TO GET MODULE TO BUILD FOR NON-N8 HARDWARE
; NEEDS TO BE FIXED BEFORE IT WILL WORK FOR ANYTHING OTHER THAN N8
#IF (!N8VENABLE)
#DEFINE N8V_OFFSET PANIC
#ENDIF
; ;
;================================================================================================== ;==================================================================================================
; ANSI EMULATION MODULE ; ANSI EMULATION MODULE
;================================================================================================== ;==================================================================================================
; ;
; The ANSI handler is a superset of the TTY handler in that is does simple
; processing of control characters such as CR, LF... But in addition is Hasbro
; a state machine driven escape sequence parser that accepts parameters and
; command characters and builds a table of data required to perform the indicated
; operation.
; For instance, a screen clear escaper sequence such as <esc>[2J is parsed as
; a leading CSI ()escape which places us in state1 (waiting for [ ). When the
; next character arrives and turns out to be [, the parser's next state is
; state2.
; State2 processing is a little more complex. If the next character is a numeral,
; it is placed in the parameter1 buffer and the next state is state3 (collecting
; parameter1).
; State3 processing implies that the buffer already has 1 byte of a parameter in
; the parameter1 buffer. If the next character is a semi-colon, that implies that
; the parameter1 buffer is complete and the next state should be state4. If the
; next byte is a numeral, it is appended to the parameter1 buffer and we stay INC
; state3. If the nect character is a semi-colon, that indicates the parameter1 is
; complete and we need to enter state4 to begin collection of parameter2. If the
; next character is neither a numeral or a semi-colon, then it needs
; to be decoded as a command. Commands result in the calling of low-level driver
; functions to perform the indicated operation. Subsequently we return to state0.
; State4 processing implies we are collecting parameter2 data. If the next byte
; is a numeral, it is assigned to the parameter2 buffer. In this case we go to
; state5 which is used to finish collection of parameter2.
; State5 processing is for collecting additional parameter2 bytes to be appended
; to the parameter2 buffer. When a non-numeral arrives, that implies that parameter2
; is complete and the new character is either a semi-colon or the awaited command
; character. If it is a semi-colon, that would imply the existance of a parameter3,
; which may or may not be supported in this implementation. If it is the command
; character, then the propper low-level driver calls need to be invoked to perform
; the desired operations on the video screen.
; Once state5 is complete, we re-enter state0.
ANSI_ERR1 .EQU 1
ANSI_CMD_DISP:
LD A,B
CP 'J'
JR ANSI_CMD_NOT_CRTCLR
; THIS IS THE CRTCLR FUNCTIONAL CODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LD DE,0 ; row 0 column 0
LD B,BF_VDASCP ; FUNCTION IS SET CURSOR POSITION
CALL EMU_VDADISP ; CALL THE VIDEO HARDWARE DRIVER
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LD DE,0 ; row 0 column 0
LD B,BF_VDAQRY ; FUNCTION IS QUERY FOR SCREEN SIZE
LD HL,0 ; WE DO NOT WANT A COPY OF THE CHARACTER BITMAP DATA
CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION
; on return, D=row count, E=column count
; for the fill call, we need hl=number of chars to fill
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LD E,' ' ; fill with spaces
;
LD A,(ANSI_ROWS) ; given A = number of rows
CALL N8V_OFFSET ; return HL = num_rows * num_cols
;
LD B,BF_VDAFIL ; FUNCTION IS FILL
CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
XOR A
RET ; return SUCCESS to caller
;
ANSI_CMD_NOT_CRTCLR:
CP 66h ; is it cursor position?
JR ANSI_CMD_NOT_CRTLC
ANSI_CMD_NOT_CRTLC:
; since only the crtclr and crtlc are supported right now...
; any other command is an error
CALL PANIC ; A has the unknown command byte
;------------------------------------------------------------------------------------
ANSI_IS_NUMERAL:
RET
;------------------------------------------------------------------------------------
ANSI_IS_ALPHA:
RET
;------------------------------------------------------------------------------------
ANSI_MARSHALL_PARM1:
RET
;------------------------------------------------------------------------------------
ANSI_MARSHALL_PARM2:
RET
;------------------------------------------------------------------------------------
ANSI_PROC_COMMAND:
RET
;------------------------------------------------------------------------------------
ANSI_STATE1:
; Waiting for [
; (the only valid character to follow an ESC would be the [ )
; (if we get something else, we go back to state0 and begin again)
LD A,B
CP '['
JR NZ,ANSI_STATE1_ERR ; if not the expected [, go around
LD HL,ANSI_STATE2 ; having found the [, set the next state
LD (ANSI_STATE),HL ; to state2 (waiting for a parm1 char).
XOR A ; set retcode to SUCCESS
RET ; and return to caller
ANSI_STATE1_ERR:
LD HL,ANSI_STATE0
LD (ANSI_STATE),HL ; set next state to state 0
LD A,ANSI_ERR1 ; "state1 expected [ not found"
RET
;------------------------------------------------------------------------------------
ANSI_STATE2:
; waiting for parm1
LD A,B
CALL ANSI_IS_NUMERAL
JR NZ,ANSI_STATE2_NOT_NUMERAL
CALL ANSI_MARSHALL_PARM1
XOR A ; set SUCCESS return code
RET
ANSI_STATE2_NOT_NUMERAL:
LD A,B
CP 59 ; semi-colon
JR NZ,ANSI_STATE2_NOT_SEMI
LD HL,ANSI_STATE3
LD (ANSI_STATE),HL ; set next state to waiting for parm2
XOR A
RET ; return SUCCESS
ANSI_STATE2_NOT_SEMI:
; if it is not a semi, or a numeral, it must be a command char
LD HL,ANSI_STATE0 ; after we do the command dispatcher, the
LD (ANSI_STATE),HL ; next state we will want is the default state
JP ANSI_CMD_DISP
; TODO:
; - SOME FUNCTIONS ARE NOT IMPLEMENTED!!!
;
ANSI_INIT: ANSI_INIT:
PRTS("ANSI: RESET$") PRTS("ANSI: RESET$")
; ;
JR ANSI_INI ; REUSE THE INI FUNCTION BELOW
JR ANSI_INI ; REUSE THE INI FUNCTION BELOW
; ;
ANSI_STATE3:
; waiting for parm2
LD A,B
CALL ANSI_IS_NUMERAL
JR NZ,ANSI_STATE3_NOT_NUMERAL
CALL ANSI_MARSHALL_PARM2
XOR A
RET
ANSI_STATE3_NOT_NUMERAL:
LD A,B
CALL ANSI_PROC_COMMAND
LD HL,ANSI_STATE0
LD (ANSI_STATE),HL
RET
; ;
; ;
ANSI_DISPATCH: ANSI_DISPATCH:
@ -196,117 +31,315 @@ ANSI_DISPATCH:
JR Z,ANSI_QRY ; $39 JR Z,ANSI_QRY ; $39
CALL PANIC CALL PANIC
; ;
;==================================================================================================
; ANSI EMULATION MODULE BIOS FUNCTION ENTRY POINTS
;==================================================================================================
; ;
; READ A CHARACTER
; ;
ANSI_IN:
ANSI_IN: ; JUST DEFER TO KEYBOARD
LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ
JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER
; ;
;
; WRITE A CHARACTER W/ EMULATION
; ;
ANSI_OUT: ANSI_OUT:
LD HL,(ANSI_STATE)
JP (HL)
;; CALL ANSI_DOCHAR ; HANDLE THE CHARACTER (EMULATION ENGINE)
;; XOR A ; SIGNAL SUCCESS
;; RET
;
LD A,E ; GET THE INCOMING CHARACTER
CP $20 ; $00-$1F IS C0
JP C,ANSI_C0DISP ; IF C0, DO C0 DISPATCH
CP $80 ; $20-$7F
JR C,ANSI_OUT1 ; HANDLE VIA STATE MACHINE
CP $A0 ; $80-$9F IS C1
JP C,ANSI_C1DISP ; IF C1, DO C1 DISPATCH
;
ANSI_OUT1: ; PROCESS OTHER CHARS VIA STATE MACHINE
LD HL,(ANSI_STATE) ; LOAD THE CURRENT STATE
CALL JPHL ; DO IT
XOR A ; SIGNAL SUCCESS
RET
; ;
; CHECK INPUT STATUS
; ;
ANSI_IST:
ANSI_IST: ; DEFER TO KEYBOARD STATUS
LD B,BF_VDAKST ; SET FUNCTION TO KEYBOARD STATUS LD B,BF_VDAKST ; SET FUNCTION TO KEYBOARD STATUS
JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER
; ;
; CHECK OUTPUT STATUS
; ;
;
ANSI_OST:
ANSI_OST: ; VIDEO OUTPUT IS *ALWAYS* READY
XOR A ; ZERO ACCUM XOR A ; ZERO ACCUM
INC A ; A := $FF TO SIGNAL OUTPUT BUFFER READY INC A ; A := $FF TO SIGNAL OUTPUT BUFFER READY
RET RET
; ;
;
; SET CONFIGURATION
; ;
ANSI_CFG: ANSI_CFG:
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
; ;
;
; INITIALIZE
; ;
ANSI_INI: ANSI_INI:
LD HL,ANSI_STATE0 ; load the address of the default state function
LD (ANSI_STATE),HL ; and place it in the ANSI_STATE variable for later.
; QUERY THE VIDEO DRIVER FOR SCREEN DIMENSIONS
LD B,BF_VDAQRY ; FUNCTION IS QUERY LD B,BF_VDAQRY ; FUNCTION IS QUERY
LD HL,0 ; WE DO NOT WANT A COPY OF THE CHARACTER BITMAP DATA LD HL,0 ; WE DO NOT WANT A COPY OF THE CHARACTER BITMAP DATA
CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION
LD (ANSI_DIM),DE ; SAVE THE SCREEN DIMENSIONS RETURNED LD (ANSI_DIM),DE ; SAVE THE SCREEN DIMENSIONS RETURNED
;
; INITIALIZE ALL WORKING VARIABLES
LD DE,0 ; DE := 0, CURSOR TO HOME POSITION 0,0 LD DE,0 ; DE := 0, CURSOR TO HOME POSITION 0,0
LD (ANSI_POS),DE ; SAVE CURSOR POSITION LD (ANSI_POS),DE ; SAVE CURSOR POSITION
LD HL,ANSI_STBASE ; SET STATE TO BASE
LD (ANSI_STATE),HL ; DO IT
;
; RESET THE CURRENT VIDEO DRIVER
LD B,BF_VDARES ; SET FUNCTION TO RESET LD B,BF_VDARES ; SET FUNCTION TO RESET
JP EMU_VDADISP ; RESET VDA AND RETURN JP EMU_VDADISP ; RESET VDA AND RETURN
; ;
;
; QUERY STATUS
; ;
ANSI_QRY: ANSI_QRY:
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
; ;
;==================================================================================================
; ANSI STATE MACHINE ENTRY POINTS
;==================================================================================================
;
ANSI_STBASE: ; STATE == BASE
JP ANSI_RENDER ; RENDER THE GLYPH
;
;
;
ANSI_STESC: ; STATE == ESCAPE SEQUENCE
RES 7,A ; CLEAR HIGH BIT
CP $30 ; $20 - $2F ARE PARAMETER CHARS
JP C,ANSI_COLLINT ; COLLECT INTERMEDIATE CHARACTERS
CP $7F ; $30 - $7E
RET NC ; IGNORE $7F
LD HL,ANSI_STBASE ; BASE STATE
LD (ANSI_STATE),HL ; SET IT
JP ANSI_ESCDISP ; DISPATCH FOR ESCAPE SEQUENCE
;
; ;
; ;
; This is probably the best place to insert a state sensitive
; dispatcher for handling ANSI escape sequences. Ansi sequences
; are unusual because they contain a number of parameters
; subsequently followed by a command character that comes last.
; It is wise to create a list of supported sequences so we know
; before writing the parser what the most complex sequence will
; consist of.
; RomWBW utilities written by Douglas Goodall only use several
; sequences. A screen clear, and a cursor position.
;
; crtclr() uses <esc>[2J
; crtlc() uses <esc>[<line>;<column><0x66>
; Programs such as wordstar use more complex operations.
;
;
;; ANSI_DOCHAR:
ANSI_STATE0:
; ANSI_STATE0 is the default state where random output characters May
; be normal visible characters, a control character such as BS, CR, LF...
; or a CSI such as an escape character (27).
LD A,E ; CHARACTER TO PROCESS
CP 8 ; BACKSPACE
JR Z,ANSI_BS
CP 12 ; FORMFEED
JR Z,ANSI_FF
CP 13 ; CARRIAGE RETURN
JR Z,ANSI_CR
CP 10 ; LINEFEED
JR Z,ANSI_LF
CP 27 ; ESCAPE ; This is the hook into the escape handler
JR NZ,ANSI_NOT_ESC ; go around if not CSI
LD HL,ANSI_STATE1
LD (ANSI_STATE),HL
XOR A ; setup SUCCESS as return status
ANSI_STCTL: ; STATE == CONTROL SEQUENCE
RES 7,A ; CLEAR HIGH BIT
CP $30
JP C,ANSI_COLLINT ; COLLECT INTERMEDIATE CHARACTERS
CP $3C
JP C,ANSI_COLLPAR ; COLLECT PARAMETERS
CP $40
JP C,ANSI_COLLPRI ; COLLECT PRIVATE CHARACTERS
CP $7F ; $30 - $7E
RET NC ; IGNORE $7F
LD HL,ANSI_STBASE ; BASE STATE
LD (ANSI_STATE),HL ; SET IT
JP ANSI_CTLDISP ; DISPATCH FOR CONTROL SEQUENCE
;
;
;
ANSI_STSTR: ; STATE == STRING DATA
RET
;
;==================================================================================================
; ANSI C0 DISPATCHING
;==================================================================================================
;
ANSI_C0DISP:
CP $08 ; BS: BACKSPACE
JP Z,ANSI_BS
CP $0A ; LF: LINEFEED
JP Z,ANSI_LF
CP $0B ; VT: VERTICAL TAB
JP Z,ANSI_LF ; TREAD AS LINEFEED
CP $0C ; FF: FORMFEED
JP Z,ANSI_LF ; TREAT AS LINEFEED
CP $0D ; CR: CARRIAGE RETURN
JP Z,ANSI_CR
CP $18 ; CAN: CANCEL
JP Z,ANSI_CAN
CP $1A ; SUB: ???
JP Z,ANSI_SUB
CP $1B ; ESC: ESCAPE
JP Z,ANSI_ESC
RET RET
ANSI_NOT_ESC:
CP 32 ; COMPARE TO SPACE (FIRST PRINTABLE CHARACTER)
RET C ; SWALLOW OTHER CONTROL CHARACTERS
; A reg has next character from BIOS CONOUT
LD B,BF_VDAWRC
;
;==================================================================================================
; ANSI C1 DISPATCHING
;==================================================================================================
;
ANSI_C1DISP:
CP $9B ; CSI: CONTROL SEQ INTRODUCER
JP Z,ANSI_CSI ; HANDLE IT
;
; IGNORE OTHERS
RET
;
;==================================================================================================
; ANSI ESCAPE SEQUENCE DISPATCHING
;==================================================================================================
;
ANSI_ESCDISP:
CP $60 ; $40-$5F
JR NC,ANSI_ESCDISP1 ; NOPE, CONTINUE
;
; $40-$5F MAP TO $80-$9F IN C1 RANGE
CALL ANSI_CLEAR ; CLEAR STATE RELATED VARIABLES
LD HL,ANSI_STBASE ; BASE STATE
LD (ANSI_STATE),HL ; SET IT
ADD A,$40 ; MAP $40-$5F -> $80-$9F
JP ANSI_C1DISP ; PROCESS AS C1 CHARACTER
;
ANSI_ESCDISP1:
; CONTINUE ESCAPE SEQ DISPATCHING
; *DEBUG*
PRTS("<ESC>($")
PUSH AF
LD A,(ANSI_INT)
OR A
CALL NZ,COUT
CALL PC_COMMA
POP AF
CALL COUT
CALL PC_RPAREN
RET
;
;==================================================================================================
; ANSI CONTROL SEQUENCE DISPATCHING
;==================================================================================================
;
ANSI_CTLDISP:
CP 'H' ; CUP: CURSOR POSITION
JP Z,ANSI_CUP
CP 'J' ; ED: ERASE IN DISPLAY
JP Z,ANSI_ED
; *DEBUG*
PUSH AF
PRTS("<CTL>($")
LD A,(ANSI_PRI)
OR A
CALL NZ,COUT
CALL PC_COMMA
LD DE,ANSI_PARLST
LD A,(ANSI_PARIDX)
INC A
CALL PRTHEXBUF
CALL PC_COMMA
LD A,(ANSI_INT)
OR A
CALL NZ,COUT
CALL PC_COMMA
POP AF
CALL COUT
CALL PC_RPAREN
RET
;
;==================================================================================================
; ANSI PROTOCOL SUPPORT FUNCTIONS
;==================================================================================================
;
; CLEAR THE WORKING VARIABLES AT START OF NEW ESC/CTL SEQUENCE
;
ANSI_CLEAR:
PUSH AF ; PRESERVE AF
LD HL,ANSI_VARS ; POINT TO VARS
LD B,ANSI_VARLEN ; B := NUMBER OF BYTES TO CLEAR
XOR A ; A := 0
;
ANSI_CLEAR1: ; LOOP
LD (HL),A ; CLEAR THE BYTE
INC HL ; BUMP POINTER
DJNZ ANSI_CLEAR1 ; LOOP AS NEEDED
;
POP AF ; RECOVER AF
RET ; DONE
;
; COLLECT INTERMEDIATE CHARACTERS
; WE DO NOT SUPPORT MORE THAN 1 WHICH IS ALL THAT IS EVER
; USED BY THE STANDARD. IF MORE THAN ONE RECEIVED, IT IS OVERLAID
;
ANSI_COLLINT:
LD (ANSI_INT),A ; RECORD INTERMEDIATE CHAR
RET ; DONE
;
; COLLECT PARAMETERS
; ';' SEPARATES PARAMETERS
; '0'-'9' ARE DIGITS OF CURRENT PARAMETER
;
ANSI_COLLPAR:
; HANDLE SEPARATOR
CP $3B ; ';' SEPARATOR?
JR NZ,ANSI_COLLPAR1 ; NOPE, CONTINUE
LD A,(ANSI_PARIDX) ; GET CURRENT PARM POS INDEX
INC A ; INCREMENT
LD (ANSI_PARIDX),A ; SAVE IT
RET ; DONE
;
ANSI_COLLPAR1: ; HANDLE '0'-'9'
CP '9' + 1 ; > '9'?
RET NC ; YUP, IGNORE CHAR
SUB '0' ; CONVERT TO BINARY VALUE
LD B,A ; SAVE VALUE IN B
LD A,(ANSI_PARIDX) ; A := CURRENT PARM INDEX
LD HL,ANSI_PARLST ; POINT TO START OF PARM LIST
LD DE,0 ; SETUP DE := 0
LD E,A ; NOW DE := PARM OFFSET
ADD HL,DE ; NOW HL := PARM BYTE TO UPDATE
LD A,(HL) ; GET CURRENT VALUE
LD C,A ; COPY TO C
RLCA ; MULTIPLY BY 10
RLCA ; "
ADD A,C ; "
RLCA ; "
ADD A,B ; ADD NEW DIGIT
LD (HL),A ; SAVE UPDATED VALUE
RET ; DONE
;
; COLLECT PRIVATE CHARACTERS
; WE DO NOT SUPPORT MORE THAN 1 WHICH IS ALL THAT IS EVER
; USED BY THE STANDARD. IF MORE THAN ONE RECEIVED, IT IS OVERLAID
;
ANSI_COLLPRI:
LD (ANSI_PRI),A ; RECORD THE PRIVATE CHARACTER
RET ; DONE
;
; CANCEL AN ESC/CTL SEQUENCE IN PROGRESS
; SOME VT TERMINALS WILL SHOW AN ERROR SYMBOL IN THIS CASE
;
ANSI_SUB:
; DISPLAY AN ERR SYMBOL???
;
; CANCEL AN ESC/CTL SEQUENCE IN PROGRESS
;
ANSI_CAN:
LD HL,ANSI_STBASE ; SET STATE TO BASE
LD (ANSI_STATE),HL ; SAVE IT
RET
;
; START AN ESC SEQ, CANCEL ANY ESC/CTL SEQUENCE IN PROGRESS
;
ANSI_ESC:
CALL ANSI_CLEAR ; CLEAR STATE RELEATED VARIABLES
LD HL,ANSI_STESC ; SET STATE TO ESCAPE SEQUENCE
LD (ANSI_STATE),HL ; SAVE IT
RET
;
; START A CTL SEQ
;
ANSI_CSI:
CALL ANSI_CLEAR ; CLEAR STATE RELEATED VARIABLES
LD HL,ANSI_STCTL ; SET STATE TO CONTROL SEQUENCE
LD (ANSI_STATE),HL ; SAVE IT
RET
;
;==================================================================================================
; ANSI FUNCTION EXECUTION
;==================================================================================================
;
ANSI_RENDER:
LD B,BF_VDAWRC ; FUNC := WRITE CHARACTER
CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER
LD A,(ANSI_COL) ; GET CUR COL LD A,(ANSI_COL) ; GET CUR COL
INC A ; INCREMENT INC A ; INCREMENT
LD (ANSI_COL),A ; SAVE IT LD (ANSI_COL),A ; SAVE IT
@ -326,7 +359,7 @@ ANSI_FF:
LD E,' ' ; FILL SCREEN WITH BLANKS LD E,' ' ; FILL SCREEN WITH BLANKS
LD B,BF_VDAFIL ; SET FUNCTION TO FILL LD B,BF_VDAFIL ; SET FUNCTION TO FILL
CALL EMU_VDADISP ; PERFORM FILL CALL EMU_VDADISP ; PERFORM FILL
JR ANSI_XY ; HOME CURSOR AND RETURN
JP ANSI_XY ; HOME CURSOR AND RETURN
; ;
ANSI_BS: ANSI_BS:
LD DE,(ANSI_POS) ; GET CURRENT ROW/COL IN DE LD DE,(ANSI_POS) ; GET CURRENT ROW/COL IN DE
@ -339,12 +372,12 @@ ANSI_BS:
LD E,' ' ; LOAD A SPACE CHARACTER LD E,' ' ; LOAD A SPACE CHARACTER
LD B,BF_VDAWRC ; SET FUNCTION TO WRITE CHARACTER LD B,BF_VDAWRC ; SET FUNCTION TO WRITE CHARACTER
CALL EMU_VDADISP ; OVERWRITE WITH A SPACE CHARACTER CALL EMU_VDADISP ; OVERWRITE WITH A SPACE CHARACTER
JR ANSI_XY ; NEED TO MOVE CURSOR BACK TO NEW TARGET COLUMN
JP ANSI_XY ; NEED TO MOVE CURSOR BACK TO NEW TARGET COLUMN
; ;
ANSI_CR: ANSI_CR:
XOR A ; ZERO ACCUM XOR A ; ZERO ACCUM
LD (ANSI_COL),A ; COL := 0 LD (ANSI_COL),A ; COL := 0
JR ANSI_XY ; REPOSITION CURSOR AND RETURN
JP ANSI_XY ; REPOSITION CURSOR AND RETURN
; ;
ANSI_LF: ANSI_LF:
LD A,(ANSI_ROW) ; GET CURRENT ROW LD A,(ANSI_ROW) ; GET CURRENT ROW
@ -363,14 +396,88 @@ ANSI_LF:
LD (ANSI_ROW),A ; SAVE IT LD (ANSI_ROW),A ; SAVE IT
JR ANSI_XY ; RESPOSITION CURSOR AND RETURN JR ANSI_XY ; RESPOSITION CURSOR AND RETURN
; ;
;
;
ANSI_CUP: ; CURSOR UPDATE
LD A,(ANSI_PARLST + 0) ; ROW PARM
LD D,A ; PUT IN D
LD A,(ANSI_PARLST + 1) ; COL PARM
LD E,A ; PUT IN E
LD (ANSI_POS),DE ; SAVE IT
JP ANSI_XY ; UPDATE CURSOR AND RETURN
;
;
;
ANSI_ED: ; ERASE IN DISPLAY
LD A,(ANSI_PARLST + 0) ; GET FIRST PARM
CP 2 ; ERASE FULL DISPLAY?
JR NZ,ANSI_ED1 ; NOPE
;
; ERASE ALL, HOME CURSOR AND TREAT AS ERASE EOS
LD DE,0 ; PREPARE TO HOME CURSOR
LD (ANSI_POS),DE ; SAVE NEW CURSOR POSITION
CALL ANSI_XY ; EXECUTE
LD A,0 ; TREAT PARM AS 0
;
ANSI_ED1: ; DETERMINE TYPE OF ERASE
CP 0 ; ERASE CURSOR TO EOS
JR Z,ANSI_ED2
CP 1 ; ERASE START THRU CURSOR
JR Z,ANSI_ED3
RET ; INVALID?
;
ANSI_ED2: ; ERASE CURSOR THRU EOL
LD DE,(ANSI_POS) ; GET CURSOR POSITION
CALL ANSI_POS2IDX ; HL NOW HAS CURSOR INDEX
PUSH HL ; SAVE IT
LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS
LD E,0 ; COL POSITION := 0
CALL ANSI_POS2IDX ; HL NOW HAS EOS INDEX
POP DE ; RECOVER CURSOR POS INDEX
OR A ; CLEAR CARRY
SBC HL,DE ; SUBTRACT CURSOR INDEX FROM EOS INDEX
LD E,' ' ; FILL WITH BLANKS
LD B,BF_VDAFIL ; SET FUNCTION TO FILL
JP EMU_VDADISP ; PERFORM FILL AND RETURN
;
ANSI_ED3: ; ERASE START THRU CURSOR
LD DE,0 ; CURSOR TO 0,0 FOR NOW
LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION
CALL EMU_VDADISP ; DO IT
LD DE,(ANSI_POS) ; GET ORIGINAL CURSOR POSITION
CALL ANSI_POS2IDX ; HL NOW HAS INDEX
INC HL ; ADD 1 POSITION TO ERASE THRU CURSOR POSITION
LD E,' ' ; FILL WITH BLANKS
LD B,BF_VDAFIL ; SET FUNCTION TO FILL
CALL EMU_VDADISP ; DO IT
JP ANSI_XY ; RESTORE CURSOR AND RETURN
;
;==================================================================================================
; SUPPORT FUNCTIONS
;==================================================================================================
;
ANSI_XY: ANSI_XY:
LD DE,(ANSI_POS) ; GET THE DESIRED CURSOR POSITION LD DE,(ANSI_POS) ; GET THE DESIRED CURSOR POSITION
LD B,BF_VDASCP ; SET FUNCTIONT TO SET CURSOR POSITION
LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION
JP EMU_VDADISP ; REPOSITION CURSOR JP EMU_VDADISP ; REPOSITION CURSOR
; ;
; The ANSI_STATE variable (word) contains the
; address of the next state function
ANSI_STATE .DW ANSI_STATE0 ; by default, ANSI_STATE0
; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL
; D=ROW, E=COL
;
ANSI_POS2IDX:
PUSH DE
LD HL,(ANSI_DIM) ; GET DIMENSIONS
LD H,L ; COLS -> H
LD E,D ; ROW NUM -> E
CALL MULT8 ; HL := H * E (ROW OFFSET)
POP DE ; RECOVER ORIGINAL ROW/COL
LD D,0 ; GET RID OF ROW COUNT
ADD HL,DE ; ADD COLUMN OFFSET
RET ; RETURN, HL HAS INDEX
;
;==================================================================================================
; WORKING DATA STORAGE
;==================================================================================================
; ;
ANSI_POS: ANSI_POS:
ANSI_COL .DB 0 ; CURRENT COLUMN - 0 BASED ANSI_COL .DB 0 ; CURRENT COLUMN - 0 BASED
@ -379,3 +486,12 @@ ANSI_ROW .DB 0 ; CURRENT ROW - 0 BASED
ANSI_DIM: ANSI_DIM:
ANSI_COLS .DB 80 ; NUMBER OF COLUMNS ON SCREEN ANSI_COLS .DB 80 ; NUMBER OF COLUMNS ON SCREEN
ANSI_ROWS .DB 24 ; NUMBER OF ROWS ON SCREEN ANSI_ROWS .DB 24 ; NUMBER OF ROWS ON SCREEN
;
ANSI_STATE .DW PANIC ; CURRENT FUNCTION FOR STATE MACHINE
;
ANSI_VARS:
ANSI_PRI .DB 0 ; PRIVATE CHARACTER RECORDED HERE
ANSI_INT .DB 0 ; INTERMEDIATE CHARACTER RECORDED HERE
ANSI_PARIDX .DB 0 ; NUMBER OF PARAMETERS RECORDED
ANSI_PARLST .FILL 16,0 ; PARAMETER VALUE LIST (UP TO 16 BYTE VALUES)
ANSI_VARLEN .EQU $ - ANSI_VARS

2
branches/wbw/Source/config_n8vem_cvdu.asm

@ -10,7 +10,7 @@ CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS
DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON
ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED)
DEFVDA .EQU VDADEV_CVDU ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) DEFVDA .EQU VDADEV_CVDU ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V)
DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...)
DEFEMU .EQU EMUTYP_ANSI ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...)
; ;
RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!!
CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA)

35
branches/wbw/Source/cvdu.asm

@ -15,9 +15,12 @@
; CVDU DRIVER - CONSTANTS ; CVDU DRIVER - CONSTANTS
;====================================================================== ;======================================================================
; ;
CVDU_STAT .EQU $E4 ; READ M8563 STATUS
CVDU_REG .EQU $E4 ; SELECT M8563 REGISTER
CVDU_DATA .EQU $EC ; READ/WRITE M8563 DATA
CVDU_STAT .EQU $E4 ; READ M8563 STATUS
CVDU_REG .EQU $E4 ; SELECT M8563 REGISTER
CVDU_DATA .EQU $EC ; READ/WRITE M8563 DATA
;
CVDU_ROWS .EQU 25
CVDU_COLS .EQU 80
; ;
;====================================================================== ;======================================================================
; CVDU DRIVER - INITIALIZATION ; CVDU DRIVER - INITIALIZATION
@ -114,7 +117,9 @@ CVDU_VDAINI:
CVDU_VDAQRY: CVDU_VDAQRY:
LD C,$00 ; MODE ZERO IS ALL WE KNOW LD C,$00 ; MODE ZERO IS ALL WE KNOW
LD DE,$1950 ; 25 ROWS ($19), 80 COLS ($50)
; LD DE,$1950 ; 25 ROWS ($19), 80 COLS ($50)
LD D,CVDU_ROWS ; ROWS
LD E,CVDU_COLS ; COLS
LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
@ -292,7 +297,7 @@ CVDU_LOADFONT1:
CVDU_XY: CVDU_XY:
LD A,E ; SAVE COLUMN NUMBER IN A LD A,E ; SAVE COLUMN NUMBER IN A
LD H,D ; SET H TO ROW NUMBER LD H,D ; SET H TO ROW NUMBER
LD E,80 ; SET E TO ROW LENGTH
LD E,CVDU_COLS ; SET E TO ROW LENGTH
CALL MULT8 ; MULTIPLY TO GET ROW OFFSET CALL MULT8 ; MULTIPLY TO GET ROW OFFSET
LD E,A ; GET COLUMN BACK LD E,A ; GET COLUMN BACK
ADD HL,DE ; ADD IT IN ADD HL,DE ; ADD IT IN
@ -390,6 +395,7 @@ CVDU_FILL3:
CALL CVDU_WR ; DO IT (SOURCE/DEST REGS AUTO INCREMENT) CALL CVDU_WR ; DO IT (SOURCE/DEST REGS AUTO INCREMENT)
LD D,0 ; CLEAR D LD D,0 ; CLEAR D
LD E,A ; SET E TO BYTES WRITTEN LD E,A ; SET E TO BYTES WRITTEN
OR A ; CLEAR CARRY
SBC HL,DE ; SUBTRACT FROM HL SBC HL,DE ; SUBTRACT FROM HL
RET Z ; IF ZERO, WE ARE DONE RET Z ; IF ZERO, WE ARE DONE
JR CVDU_FILL2 ; OTHERWISE, WRITE SOME MORE JR CVDU_FILL2 ; OTHERWISE, WRITE SOME MORE
@ -423,17 +429,17 @@ CVDU_SCROLL1:
CALL CVDU_WRX ; DO IT CALL CVDU_WRX ; DO IT
; COMPUTE SOURCE (INCREMENT ONE ROW) ; COMPUTE SOURCE (INCREMENT ONE ROW)
LD DE,80 ; SOURCE ADDRESS IS ONE ROW PAST DESTINATION
LD DE,CVDU_COLS ; SOURCE ADDRESS IS ONE ROW PAST DESTINATION
ADD HL,DE ; ADD IT TO BUF ADDRESS ADD HL,DE ; ADD IT TO BUF ADDRESS
; SET INITIAL BLOCK COPY SOURCE ; SET INITIAL BLOCK COPY SOURCE
LD C,32 ; BLOCK START ADDRESS REGISTER LD C,32 ; BLOCK START ADDRESS REGISTER
CALL CVDU_WRX ; DO IT CALL CVDU_WRX ; DO IT
LD B,23 ; ITERATIONS (ROWS - 1)
LD B,CVDU_ROWS - 1 ; ITERATIONS (ROWS - 1)
CVDU_SCROLL2: CVDU_SCROLL2:
; SET BLOCK COPY COUNT (WILL EXECUTE COPY) ; SET BLOCK COPY COUNT (WILL EXECUTE COPY)
LD A,80 ; COPY 80 BYTES
LD A,CVDU_COLS ; COPY 80 BYTES
LD C,30 ; WORD COUNT REGISTER LD C,30 ; WORD COUNT REGISTER
CALL CVDU_WR ; DO IT CALL CVDU_WR ; DO IT
@ -465,12 +471,12 @@ CVDU_SCROLL2:
CVDU_RSCROLL: CVDU_RSCROLL:
; SCROLL THE CHARACTER BUFFER ; SCROLL THE CHARACTER BUFFER
LD A,'=' ; CHAR VALUE TO FILL NEW EXPOSED LINE LD A,'=' ; CHAR VALUE TO FILL NEW EXPOSED LINE
LD HL,80*23 ; SOURCE ADDRESS OF CHARACER BUFFER (LINE 24)
LD HL,$0 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF CHARACER BUFFER
CALL CVDU_RSCROLL1 ; SCROLL CHARACTER BUFFER CALL CVDU_RSCROLL1 ; SCROLL CHARACTER BUFFER
; SCROLL THE ATTRIBUTE BUFFER ; SCROLL THE ATTRIBUTE BUFFER
LD A,(CVDU_ATTR) ; ATTRIBUTE VALUE TO FILL NEW EXPOSED LINE LD A,(CVDU_ATTR) ; ATTRIBUTE VALUE TO FILL NEW EXPOSED LINE
LD HL,$800+(80*23) ; SOURCE ADDRESS OF ATTRIBUTE BUFFER (LINE 24)
LD HL,$800 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF ATTRIBUTE BUFFER
JR CVDU_RSCROLL1 ; SCROLL ATTRIBUTE BUFFER AND RETURN JR CVDU_RSCROLL1 ; SCROLL ATTRIBUTE BUFFER AND RETURN
CVDU_RSCROLL1: CVDU_RSCROLL1:
@ -483,7 +489,7 @@ CVDU_RSCROLL1:
CALL CVDU_WR ; DO IT CALL CVDU_WR ; DO IT
; LOOP TO SCROLL EACH LINE WORKING FROM BOTTOM TO TOP ; LOOP TO SCROLL EACH LINE WORKING FROM BOTTOM TO TOP
LD B,23 ; ITERATIONS (23 ROWS)
LD B,CVDU_ROWS - 1 ; ITERATIONS (ROWS - 1)
CVDU_RSCROLL2: CVDU_RSCROLL2:
; SET BLOCK COPY DESTINATION (USING HL PASSED IN) ; SET BLOCK COPY DESTINATION (USING HL PASSED IN)
@ -491,7 +497,8 @@ CVDU_RSCROLL2:
CALL CVDU_WRX ; DO IT CALL CVDU_WRX ; DO IT
; COMPUTE SOURCE (DECREMENT ONE ROW) ; COMPUTE SOURCE (DECREMENT ONE ROW)
LD DE,80 ; SOURCE ADDRESS IS ONE ROW PAST DESTINATION
LD DE,CVDU_COLS ; SOURCE ADDRESS IS ONE ROW PAST DESTINATION
OR A ; CLEAR CARRY
SBC HL,DE ; SUBTRACT IT FROM BUF ADDRESS SBC HL,DE ; SUBTRACT IT FROM BUF ADDRESS
; SET BLOCK COPY SOURCE ; SET BLOCK COPY SOURCE
@ -499,7 +506,7 @@ CVDU_RSCROLL2:
CALL CVDU_WRX ; DO IT CALL CVDU_WRX ; DO IT
; SET BLOCK COPY COUNT (WILL EXECUTE COPY) ; SET BLOCK COPY COUNT (WILL EXECUTE COPY)
LD A,80 ; COPY 80 BYTES
LD A,CVDU_COLS ; COPY 80 BYTES
LD C,30 ; WORD COUNT REGISTER LD C,30 ; WORD COUNT REGISTER
CALL CVDU_WR ; DO IT CALL CVDU_WR ; DO IT
@ -517,7 +524,7 @@ CVDU_RSCROLL2:
CALL CVDU_WR ; DO IT CALL CVDU_WR ; DO IT
; SET BLOCK WRITE COUNT (WILL EXECUTE THE WRITE) ; SET BLOCK WRITE COUNT (WILL EXECUTE THE WRITE)
LD A,80 - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN)
LD A,CVDU_COLS - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN)
LD C,30 ; WORD COUNT REGISTER LD C,30 ; WORD COUNT REGISTER
CALL CVDU_WR ; DO IT CALL CVDU_WR ; DO IT

367
branches/wbw/Source/ppide.asm

@ -60,6 +60,7 @@ PPIDE_RST_LINE .EQU 80H ; INVERTER BETWEEN 8255 AND IDE INTERFACE
; ;
PPIDE_DATA .EQU PPIDE_CS0_LINE PPIDE_DATA .EQU PPIDE_CS0_LINE
PPIDE_ERROR .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE PPIDE_ERROR .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE
PPIDE_FEATURE .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE
PPIDE_SEC_CNT .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE PPIDE_SEC_CNT .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE
PPIDE_SECTOR .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE PPIDE_SECTOR .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE
PPIDE_CYL_LSB .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE PPIDE_CYL_LSB .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE
@ -175,19 +176,18 @@ PPIDE_RW:
#IF (PPIDE8BIT) #IF (PPIDE8BIT)
CALL PPIDE_WAITRDY CALL PPIDE_WAITRDY
LD C,01H
LD A,PPIDE_ERROR
CALL PPIDE_WRITE
LD C,PPIDECMD_SETFEAT
LD A,PPIDE_COMMAND
CALL PPIDE_WRITE
LD C,PPIDE_FEATURE ; IDE FEATURE REGISTER
LD A,01H ; VALUE := 1
CALL PPIDE_WRITE ; DO IT
LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER
LD A,PPIDECMD_SETFEAT ; SET FEATURE
CALL PPIDE_WRITE ; DO IT
CALL PPIDE_WAITRDY CALL PPIDE_WAITRDY
JP NC,PPIDE_ERR JP NC,PPIDE_ERR
CALL PPIDE_CHKERR ; CHECK FOR ERRORS CALL PPIDE_CHKERR ; CHECK FOR ERRORS
JP NC,PPIDE_ERR JP NC,PPIDE_ERR
#IF (PPIDETRACE >= 2) #IF (PPIDETRACE >= 2)
CALL IDE_PRT
CALL PPIDE_PRT
#ENDIF #ENDIF
#ENDIF #ENDIF
@ -195,10 +195,9 @@ PPIDE_RW0:
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
JP NC,PPIDE_ERR JP NC,PPIDE_ERR
CALL PPIDE_SETUP ; SETUP CYL, TRK, HEAD CALL PPIDE_SETUP ; SETUP CYL, TRK, HEAD
LD A,(PPIDEP_CMD)
LD C,A
LD A,PPIDE_COMMAND
CALL PPIDE_WRITE
LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER
LD A,(PPIDEP_CMD) ; COMMAND VALUE
CALL PPIDE_WRITE ; DO IT
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
JP NC,PPIDE_ERR JP NC,PPIDE_ERR
CALL PPIDE_CHKERR ; CHECK FOR ERRORS CALL PPIDE_CHKERR ; CHECK FOR ERRORS
@ -246,14 +245,14 @@ PPIDE_OK:
; ;
; ;
PPIDE_RESET: PPIDE_RESET:
LD C,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES
LD A,PPIDE_CONTROL
CALL PPIDE_WRITE
LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER
LD A,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES
CALL PPIDE_WRITE ; DO IT
LD DE,8 ; DELAY ABOUT 200ms LD DE,8 ; DELAY ABOUT 200ms
CALL VDELAY CALL VDELAY
LD C,000000010B ; NO INTERRUPTS, DEASSERT RESET
LD A,PPIDE_CONTROL
CALL PPIDE_WRITE
LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER
LD A,000000010B ; NO INTERRUPTS, DEASSERT RESET
CALL PPIDE_WRITE ; DO IT
XOR A ; STATUS OK XOR A ; STATUS OK
LD (PPIDE_STAT),A ; SAVE IT LD (PPIDE_STAT),A ; SAVE IT
@ -272,9 +271,8 @@ PPIDE_WBSY:
LD A,D LD A,D
OR E OR E
JP Z,PPIDE_TO JP Z,PPIDE_TO
LD A,PPIDE_STTS
CALL PPIDE_READ
LD A,C
LD C,PPIDE_STTS ; IDE STATUS REGISTER
CALL PPIDE_READ ; READ ID
LD (PPIDEP_STTS),A ; SAVE IT LD (PPIDEP_STTS),A ; SAVE IT
AND 011000000B ; ISOLATE BUSY AND RDY BITS AND 011000000B ; ISOLATE BUSY AND RDY BITS
XOR 001000000B ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 XOR 001000000B ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1
@ -290,22 +288,20 @@ PPIDE_TO:
; ;
; ;
PPIDE_CHKERR: PPIDE_CHKERR:
LD A,PPIDE_STTS
CALL PPIDE_READ
LD A,C
LD C,PPIDE_STTS ; IDE STATUS REGISTER
CALL PPIDE_READ ; READ IT
LD (PPIDEP_STTS),A ; SAVE IT LD (PPIDEP_STTS),A ; SAVE IT
AND 000000001B ; ERROR BIT SET? AND 000000001B ; ERROR BIT SET?
SCF ; ASSUME NO ERR SCF ; ASSUME NO ERR
RET Z ; NO ERR, RETURN WITH CF SET RET Z ; NO ERR, RETURN WITH CF SET
LD A,PPIDE_ERROR
CALL PPIDE_READ
LD A,C
;
LD C,PPIDE_ERROR ; IDE ERROR REGISTER
CALL PPIDE_READ ; READ IT
LD (PPIDEP_ERR),A ; SAVE IT LD (PPIDEP_ERR),A ; SAVE IT
;
LD A,PPIDERC_CMDERR ; COMMAND ERROR LD A,PPIDERC_CMDERR ; COMMAND ERROR
LD (PPIDE_RC),A ; SAVE IT LD (PPIDE_RC),A ; SAVE IT
;
OR A ; CLEAR CF TO SIGNAL ERROR OR A ; CLEAR CF TO SIGNAL ERROR
RET RET
; ;
@ -319,9 +315,8 @@ PPIDE_WDRQ:
LD A,D LD A,D
OR E OR E
JP Z,PPIDE_TO2 JP Z,PPIDE_TO2
LD A,PPIDE_STTS
CALL PPIDE_READ
LD A,C
LD C,PPIDE_STTS ; IDE STATUS REGISTER
CALL PPIDE_READ ; READ IT
LD (PPIDEP_STTS),A ; SAVE IT LD (PPIDEP_STTS),A ; SAVE IT
AND 010001000B ; TO FILL (OR READY TO FILL) AND 010001000B ; TO FILL (OR READY TO FILL)
XOR 000001000B XOR 000001000B
@ -336,73 +331,110 @@ PPIDE_TO2:
; ;
; ;
; ;
#IF (PPIDE8BIT)
PPIDE_BUFRD: PPIDE_BUFRD:
LD HL,(DIOBUF)
LD DE,200H
PPIDE_BUFRD1:
LD A,PPIDE_DATA
CALL PPIDE_READ
LD (HL),C
INC HL
DEC DE
LD A,D
OR E
JP NZ,PPIDE_BUFRD1
RET
#ELSE
PPIDE_BUFRD:
LD HL,(DIOBUF)
LD D,0
PPIDE_BUFRD1:
LD A,PPIDE_DATA
CALL PPIDE_READ
LD (HL),C
INC HL
LD (HL),B
INC HL
DEC D
JP NZ,PPIDE_BUFRD1
; SETUP PPI TO READ
LD A,RD_IDE_8255 ; READ CONFIG
OUT (PPI1CONT),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
;
; SELECT READ/WRITE IDE REGISTER
LD A,PPIDE_DATA ; DATA REGISTER
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
LD E,A ; E := READ UNASSERTED
XOR PPIDE_RD_LINE ; SWAP THE READ LINE BIT
LD D,A ; D := READ ASSERTED
;
; LOOP SETUP
LD HL,(DIOBUF) ; LOCATION OF BUFFER
LD B,0 ; 256 ITERATIONS
LD C,IDEMSB ; SETUP C WITH IO PORT (MSB)
;
CALL PPIDE_BUFRD1 ; FIRST PASS (FIRST 256 BYTES)
CALL PPIDE_BUFRD1 ; SECOND PASS (LAST 256 BYTES)
;
; CLEAN UP
XOR A ; ZERO A
OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS
RECOVERY ; OPTIONAL SMALL DELAY
RET RET
;
PPIDE_BUFRD1: ; START OF READ LOOP
#IF (!PPIDE8BIT)
DEC C ; MSB -> LSB
#ENDIF #ENDIF
LD A,D ; ASSERT READ
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
INI ; GET AND SAVE NEXT BYTE
RECOVERY ; OPTIONAL SMALL DELAY
#IF (!PPIDE8BIT)
INC C ; LSB -> MSB
INI ; GET AND SAVE NEXT BYTE
RECOVERY ; OPTIONAL SMALL DELAY
#ENDIF
LD A,E ; DEASSERT READ
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
JR NZ,PPIDE_BUFRD1 ; LOOP UNTIL DONE
RET
; ;
; ;
; ;
#IF (PPIDE8BIT)
PPIDE_BUFWR: PPIDE_BUFWR:
LD HL,(DIOBUF)
LD DE,200H
PPIDE_BUFWR1:
LD C,(HL)
LD A,PPIDE_DATA
CALL PPIDE_WRITE
INC HL
DEC DE
LD A,D
OR E
JP NZ,PPIDE_BUFWR1
#ELSE
PPIDE_BUFWR:
LD HL,(DIOBUF)
LD D,0
PPIDE_BUFWR1:
LD C,(HL)
INC HL
LD B,(HL)
INC HL
LD A,PPIDE_DATA
CALL PPIDE_WRITE
DEC D
JP NZ,PPIDE_BUFWR1
; SETUP PPI TO WRITE
LD A,WR_IDE_8255 ; READ CONFIG
OUT (PPI1CONT),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
;
; SELECT READ/WRITE IDE REGISTER
LD A,PPIDE_DATA ; DATA REGISTER
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
LD E,A ; E := READ UNASSERTED
XOR PPIDE_WR_LINE ; SWAP THE WRITE LINE BIT
LD D,A ; D := READ ASSERTED
;
; LOOP SETUP
LD HL,(DIOBUF) ; LOCATION OF BUFFER
LD B,0 ; 256 ITERATIONS
LD C,IDEMSB ; SETUP C WITH IO PORT (MSB)
;
CALL PPIDE_BUFWR1 ; FIRST PASS (FIRST 256 BYTES)
CALL PPIDE_BUFWR1 ; SECOND PASS (LAST 256 BYTES)
;
; CLEAN UP
XOR A ; ZERO A
OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS
RECOVERY ; OPTIONAL SMALL DELAY
RET RET
;
PPIDE_BUFWR1: ; START OF READ LOOP
#IF (!PPIDE8BIT)
DEC C ; MSB -> LSB
#ENDIF
OUTI ; SEND NEXT BYTE OF BUFFER
RECOVERY ; OPTIONAL SMALL DELAY
#IF (!PPIDE8BIT)
INC C ; LSB -> MSB
OUTI ; SEND NEXT BYTE OF BUFFER
RECOVERY ; OPTIONAL SMALL DELAY
#ENDIF #ENDIF
LD A,D ; ASSERT WRITE
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
LD A,E ; DEASSERT WRITE
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
JR NZ,PPIDE_BUFWR1 ; LOOP UNTIL DONE
RET
; ;
; ;
; ;
PPIDE_SETUP: PPIDE_SETUP:
LD C,1
LD A,PPIDE_SEC_CNT
CALL PPIDE_WRITE
LD C,PPIDE_SEC_CNT ; IDE SECTOR COUNT REGISTER
LD A,1 ; 1 SECTOR
CALL PPIDE_WRITE ; DO IT
LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT
AND 0FH AND 0FH
@ -420,29 +452,25 @@ PPIDE_SETUP_UNIT1:
; LD DE,(PPIDE1_OFFSET) ; LD DE,(PPIDE1_OFFSET)
JP PPIDE_SETUP1 JP PPIDE_SETUP1
PPIDE_SETUP1: PPIDE_SETUP1:
LD (PPIDEP_HEAD),A
LD C,A
LD A,PPIDE_HEAD
CALL PPIDE_WRITE
LD C,PPIDE_HEAD ; IDE HEAD REGISTER
LD (PPIDEP_HEAD),A ; SAVE HEAD VALUE
CALL PPIDE_WRITE ; WRITE IT
LD HL,(HSTTRK) ; HSTTRK -> IDECYLHI/LO LD HL,(HSTTRK) ; HSTTRK -> IDECYLHI/LO
LD A,H
LD (PPIDEP_CYLHI),A
LD C,A
LD A,PPIDE_CYL_MSB
CALL PPIDE_WRITE
LD A,L
LD (PPIDEP_CYLLO),A
LD C,A
LD A,PPIDE_CYL_LSB
CALL PPIDE_WRITE
LD BC,(HSTSEC) ; HSTSEC -> IDESECTN
LD A,C
LD (PPIDEP_SEC),A
LD C,A
LD A,PPIDE_SECTOR
CALL PPIDE_WRITE
LD C,PPIDE_CYL_MSB ; IDE MSB CYL REGISTER
LD A,H ; MSB CYL VALUE
LD (PPIDEP_CYLHI),A ; SAVE IT
CALL PPIDE_WRITE ; WRITE IT
LD C,PPIDE_CYL_LSB ; IDE LSB CYL REGISTER
LD A,L ; LSB CYL VALUE
LD (PPIDEP_CYLLO),A ; SAVE IT
CALL PPIDE_WRITE ; WRITE IT
LD HL,(HSTSEC) ; HSTSEC -> IDESECTN
LD C,PPIDE_SECTOR ; IDE SECTOR REGISTER
LD A,L ; SECTOR VALUE
LD (PPIDEP_SEC),A ; SAVE IT
CALL PPIDE_WRITE ; WRITE IT
#IF (DSKYENABLE) #IF (DSKYENABLE)
CALL PPIDE_DSKY CALL PPIDE_DSKY
@ -453,70 +481,63 @@ PPIDE_SETUP1:
; ;
; ;
PPIDE_READ: PPIDE_READ:
PUSH AF ; save register value
LD A,RD_IDE_8255
OUT (PPI1CONT),A ; Config 8255 chip, read mode
RECOVERY
POP AF ; restore register value
OUT (IDECTL),A ; Drive address onto control lines
RECOVERY
OR PPIDE_RD_LINE ; assert RD pin
OUT (IDECTL),A
RECOVERY
PUSH AF ; save register value
IN A,(IDELSB) ; read lower byte
RECOVERY
LD C,A ; save in reg C
IN A,(IDEMSB) ; read upper byte
RECOVERY
LD B,A ; save in reg C
POP AF ; restore register value
XOR PPIDE_RD_LINE ; de-assert RD signal
OUT (IDECTL),A
RECOVERY
XOR A
OUT (IDECTL),A ; Deassert all control pins
RECOVERY
RET
;
; SET PPI MODE TO READ CONFIGURATION
LD A,RD_IDE_8255 ; PPI MODE TO READ
OUT (PPI1CONT),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
;
; SELECT REQUESTED IDE REGISTER AND ASSERT READ
LD A,C ; REGISTER SELECTION -> A
OR PPIDE_RD_LINE ; ASSERT READ
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
;
; READ THE BYTE
IN A,(IDELSB) ; READ LSB
RECOVERY ; OPTIONAL SMALL DELAY
PUSH AF ; SAVE IT FOR NOW
;
; CLEAN UP AND RETURN
XOR A ; ZERO A
OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS
RECOVERY ; OPTIONAL SMALL DELAY
;
POP AF ; RECOVER THE DATA BYTE
RET ; RETURN
; ;
; ;
; ;
PPIDE_WRITE: PPIDE_WRITE:
PUSH AF ; save IDE register value
LD A,WR_IDE_8255
OUT (PPI1CONT),A ; Config 8255 chip, write mode
RECOVERY
LD A,C ; get value to be written
OUT (IDELSB),A
RECOVERY
LD A,B ; get value to be written
OUT (IDEMSB),A
RECOVERY
POP AF ; get saved IDE register
OUT (IDECTL),A ; Drive address onto control lines
RECOVERY
OR PPIDE_WR_LINE ; assert write pin
OUT (IDECTL),A
RECOVERY
XOR PPIDE_WR_LINE ; de assert WR pin
OUT (IDECTL),A ; Drive address onto control lines
RECOVERY
XOR A
OUT (IDECTL),A ; release bus signals
RECOVERY
RET
;
; SAVE THE INCOMING VALUE TO WRITE
PUSH AF
;
; SET PPI MODE TO WRITE CONFIGURATION
LD A,WR_IDE_8255 ; PPI MODE TO WRITE
OUT (PPI1CONT),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
;
; SET THE VALUE TO WRITE
POP AF ; GET VALUE BACK
OUT (IDELSB),A ; SET IDE LSB
RECOVERY ; OPTIONAL SMALL DELAY
; XOR A ; ZERO A
; OUT (IDELSB),A ; SET IDE MSB
; RECOVERY ; OPTIONAL SMALL DELAY
;
; PULSE THE WRITE LINE
LD A,C ; REGISTER SELECTION -> A
OR PPIDE_WR_LINE ; ASSERT WRITE
OUT (IDECTL),A ; DO IT
RECOVERY ; OPTIONAL SMALL DELAY
;
; CLEAN UP AND RETURN
XOR A ; ZERO A
OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS
RECOVERY ; OPTIONAL SMALL DELAY
;
RET ; RETURN
; ;
; ;
; ;
@ -581,15 +602,13 @@ PPIDE_PRTCMD:
CALL WRITESTR CALL WRITESTR
CALL PC_SPACE CALL PC_SPACE
LD A,PPIDE_STTS
CALL PPIDE_READ
LD A,C
LD C,PPIDE_STTS ; IDE STATUS REGISTER
CALL PPIDE_READ ; READ IT
CALL PRTHEXBYTE CALL PRTHEXBYTE
CALL PC_SPACE CALL PC_SPACE
LD A,PPIDE_ERROR
CALL PPIDE_READ
LD A,C
LD C,PPIDE_ERROR ; IDE ERROR REGISTER
CALL PPIDE_READ ; READ IT
CALL PRTHEXBYTE CALL PRTHEXBYTE
CALL PC_SPACE CALL PC_SPACE

169
branches/wbw/Source/std.asm

@ -112,6 +112,11 @@ EMUTYP_NONE .EQU 0
EMUTYP_TTY .EQU 1 EMUTYP_TTY .EQU 1
EMUTYP_ANSI .EQU 2 EMUTYP_ANSI .EQU 2
; ;
; SCSI DEVICE PERSONALITY CHOICES
;
S2I_PER_N8VEM .EQU 1
S2I_PER_ST125N .EQU 2
;
; SYSTEM GENERATION SETTINGS ; SYSTEM GENERATION SETTINGS
; ;
SYS_CPM .EQU 1 ; CPM (IMPLIES BDOS + CCP) SYS_CPM .EQU 1 ; CPM (IMPLIES BDOS + CCP)
@ -152,10 +157,14 @@ CP .EQU CP_ZCPR
; ;
; INCLUDE PLATFORM SPECIFIC HARDWARE DEFINITIONS ; INCLUDE PLATFORM SPECIFIC HARDWARE DEFINITIONS
; ;
#IF ((PLATFORM == PLT_N8VEM) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_S2I))
#IF ((PLATFORM == PLT_N8VEM) | (PLATFORM == PLT_ZETA))
#INCLUDE "n8vem.inc" #INCLUDE "n8vem.inc"
#ENDIF #ENDIF
; ;
#IF (PLATFORM == PLT_S2I)
#INCLUDE "s2i.inc"
#ENDIF
;
#IF (PLATFORM == PLT_N8) #IF (PLATFORM == PLT_N8)
#INCLUDE "n8.inc" #INCLUDE "n8.inc"
#ENDIF #ENDIF
@ -340,171 +349,21 @@ BIOS: .EQU CCP+1600H ; BASE OF BIOS
CCPSIZ: .EQU 00800H CCPSIZ: .EQU 00800H
; ;
#IF (PLATFORM == PLT_N8VEM) #IF (PLATFORM == PLT_N8VEM)
#DEFINE PLATFORM_NAME "N8VEM Z80 SBC"
#DEFINE PLATFORM_NAME "N8VEM Z80"
#ENDIF #ENDIF
#IF (PLATFORM == PLT_ZETA) #IF (PLATFORM == PLT_ZETA)
#DEFINE PLATFORM_NAME "ZETA Z80 SBC"
#DEFINE PLATFORM_NAME "ZETA Z80"
#ENDIF #ENDIF
#IF (PLATFORM == PLT_N8) #IF (PLATFORM == PLT_N8)
#DEFINE PLATFORM_NAME "N8 Z180 SBC"
#DEFINE PLATFORM_NAME "N8 Z180"
#ENDIF #ENDIF
#IF (PLATFORM == PLT_S2I) #IF (PLATFORM == PLT_S2I)
#DEFINE PLATFORM_NAME "SCSI2IDE"
#DEFINE PLATFORM_NAME "SCSI2IDE Z80"
#ENDIF #ENDIF
#IF (PLATFORM == PLT_S100) #IF (PLATFORM == PLT_S100)
#DEFINE PLATFORM_NAME "S100" #DEFINE PLATFORM_NAME "S100"
#ENDIF #ENDIF
; ;
#IF (DSKYENABLE)
#DEFINE DSKYLBL ", DSKY"
#ELSE
#DEFINE DSKYLBL ""
#ENDIF
;
#IF (VDUENABLE)
#DEFINE VDULBL ", VDU"
#ELSE
#DEFINE VDULBL ""
#ENDIF
;
#IF (CVDUENABLE)
#DEFINE CVDULBL ", CVDU"
#ELSE
#DEFINE CVDULBL ""
#ENDIF
;
#IF (UPD7220ENABLE)
#DEFINE UPD7220LBL ", UPD7220"
#ELSE
#DEFINE UPD7220LBL ""
#ENDIF
;
#IF (N8VENABLE)
#DEFINE N8VLBL ", N8V"
#ELSE
#DEFINE N8VLBL ""
#ENDIF
;
#IF (FDENABLE)
#IF (FDMAUTO)
#DEFINE FDLBL ", FLOPPY (AUTOSIZE)"
#ELSE
#IF (FDMEDIA == FDM720)
#DEFINE FDLBL ", FLOPPY (360KB)"
#ENDIF
#IF (FDMEDIA == FDM111)
#DEFINE FDLBL ", FLOPPY (1.11MB)"
#ENDIF
#ENDIF
#ELSE
#DEFINE FDLBL ""
#ENDIF
;
#IF (IDEENABLE)
#IF (IDEMODE == IDEMODE_DIO)
#DEFINE IDELBL ", IDE (DISKIO)"
#ENDIF
#IF (IDEMODE == IDEMODE_DIDE)
#DEFINE IDELBL ", IDE (DUAL IDE)"
#ENDIF
#ELSE
#DEFINE IDELBL ""
#ENDIF
;
#IF (PPIDEENABLE)
#IF (PPIDEMODE == PPIDEMODE_STD)
#DEFINE PPIDELBL ", PPIDE (STD)"
#ENDIF
#IF (PPIDEMODE == PPIDEMODE_DIO3)
#DEFINE PPIDELBL ", PPIDE (DISKIO V3)"
#ENDIF
#ELSE
#DEFINE PPIDELBL ""
#ENDIF
;
#IF (SDENABLE)
#DEFINE SDLBL ", SD CARD"
#ELSE
#DEFINE SDLBL ""
#ENDIF
;
#IF (IDEENABLE)
#DEFINE IDELBL ", IDE"
#ELSE
#DEFINE IDELBL ""
#ENDIF
;
#IF (PPIDEENABLE)
#DEFINE PPIDELBL ", PPIDE"
#ELSE
#DEFINE PPIDELBL ""
#ENDIF
#IF (SDENABLE)
#DEFINE SDLBL ", SD CARD"
#ELSE
#DEFINE SDLBL ""
#ENDIF
#IF (HDSKENABLE)
#DEFINE HDSKLBL ", SIMH DISK"
#ELSE
#DEFINE HDSKLBL ""
#ENDIF
#IF (PRPENABLE)
#IF (PRPCONENABLE & PRPSDENABLE)
#DEFINE PRPLBL ", PROPIO (CONSOLE, SD CARD)"
#ENDIF
#IF (PRPCONENABLE & !PRPSDENABLE)
#DEFINE PRPLBL ", PROPIO (CONSOLE)"
#ENDIF
#IF (!PRPCONENABLE & PRPSDENABLE)
#DEFINE PRPLBL ", PROPIO (SD CARD)"
#ENDIF
#IF (!PRPCONENABLE & !PRPSDENABLE)
#DEFINE PRPLBL ", PROPIO ()"
#ENDIF
#ELSE
#DEFINE PRPLBL ""
#ENDIF
#IF (PPPENABLE)
#IF (PPPCONENABLE & PPPSDENABLE)
#DEFINE PPPLBL ", PARPORTPROP (CONSOLE, SD CARD)"
#ENDIF
#IF (PPPCONENABLE & !PPPSDENABLE)
#DEFINE PPPLBL ", PARPORTPROP (CONSOLE)"
#ENDIF
#IF (!PPPCONENABLE & PPPSDENABLE)
#DEFINE PPPLBL ", PARPORTPROP (SD CARD)"
#ENDIF
#IF (!PPPCONENABLE & !PPPSDENABLE)
#DEFINE PPPLBL ", PARPORTPROP ()"
#ENDIF
#ELSE
#DEFINE PPPLBL ""
#ENDIF
#IFDEF (HISTENABLE)
#DEFINE HISTLBL ", HIST"
#ELSE
#DEFINE HISTLBL ""
#ENDIF
.ECHO "Configuration: "
.ECHO PLATFORM_NAME
.ECHO DSKYLBL
.ECHO VDULBL
.ECHO FDLBL
.ECHO IDELBL
.ECHO PPIDELBL
.ECHO SDLBL
.ECHO PRPLBL
.ECHO PPPLBL
.ECHO HISTLBL
.ECHO "\n"
;
; HELPER MACROS ; HELPER MACROS
; ;
#DEFINE PRTC(C) CALL PRTCH \ .DB C ; PRINT CHARACTER C TO CONSOLE - PRTC('X') #DEFINE PRTC(C) CALL PRTCH \ .DB C ; PRINT CHARACTER C TO CONSOLE - PRTC('X')

Loading…
Cancel
Save