diff --git a/branches/wbw/Apps/apps-bins/comfiles.lbr b/branches/wbw/Apps/apps-bins/comfiles.lbr index 70aa450d..32ef841f 100644 Binary files a/branches/wbw/Apps/apps-bins/comfiles.lbr and b/branches/wbw/Apps/apps-bins/comfiles.lbr differ diff --git a/branches/wbw/Apps/apps-srcs/sources.lbr b/branches/wbw/Apps/apps-srcs/sources.lbr index d0b5a4f3..f24229a6 100644 Binary files a/branches/wbw/Apps/apps-srcs/sources.lbr and b/branches/wbw/Apps/apps-srcs/sources.lbr differ diff --git a/branches/wbw/Apps/crossdev/readme.1st b/branches/wbw/Apps/crossdev/readme.1st new file mode 100644 index 00000000..64aaab57 --- /dev/null +++ b/branches/wbw/Apps/crossdev/readme.1st @@ -0,0 +1,20 @@ +This directory has the files that comprise a cross development +environment for building C utility programs. + +The program files located here are not current but rather represent +a snapshot from a recent time. If you wanted to compile any of the +current apps from RomWBW, you would have too unpack the sources in +/RomWBW/trunk/Apps/apps-srcs and copy them to this folder, being careful +to usde upper case filenames. + +The build is set up in sort of a microsoft-like folder arrangement +with files generated being placed in either the DEBUG or RELEASE folder. + +The actual apps for RomWBW are generated directly on CP/M-80- v2.2 +using native language tools, it's the "CP/M way". + +Have fun, + +Douglas Goodall +Santa Maria, CA +douglas_goodall@mac.com diff --git a/branches/wbw/Apps/dougs-devo/allfiles.lbr b/branches/wbw/Apps/dougs-devo/allfiles.lbr new file mode 100644 index 00000000..93fe9a1c Binary files /dev/null and b/branches/wbw/Apps/dougs-devo/allfiles.lbr differ diff --git a/branches/wbw/Apps/dougs-devo/readme.txt b/branches/wbw/Apps/dougs-devo/readme.txt new file mode 100644 index 00000000..4af8a352 --- /dev/null +++ b/branches/wbw/Apps/dougs-devo/readme.txt @@ -0,0 +1,12 @@ +This file, "allfiles.lbr" is the complete contents of my A: drive, +on which I develop all my apps and utilities. Once you have your +system running with storage (ppide,ide,sd,...), configure to use +DM_PPIDE or similar so the mass storage is on A: B: C: & D:. + +Unpack this file onto A: and you will be all set to build the apps. + +You will also have enough to get you going writing your own. + +Good luck, + +Douglas Goodall diff --git a/branches/wbw/Source/ansi.asm b/branches/wbw/Source/ansi.asm index b6a989b4..16f0ed93 100644 --- a/branches/wbw/Source/ansi.asm +++ b/branches/wbw/Source/ansi.asm @@ -3,13 +3,167 @@ ; ANSI EMULATION MODULE ;================================================================================================== ; -; TODO: -; - THIS IS CURRENTLY JUST A CLONE OF TTY.ASM! NEEDS A REAL IMPLEMENTATION! -; - SOME FUNCTIONS ARE NOT IMPLEMENTED! -; + +; 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 [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 + ANSI_INIT: 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: @@ -39,9 +193,13 @@ ANSI_IN: ; ; ANSI_OUT: - CALL ANSI_DOCHAR ; HANDLE THE CHARACTER (EMULATION ENGINE) - XOR A ; SIGNAL SUCCESS - RET + LD HL,(ANSI_STATE) + JP (HL) + +;; CALL ANSI_DOCHAR ; HANDLE THE CHARACTER (EMULATION ENGINE) +;; XOR A ; SIGNAL SUCCESS +;; RET + ; ; ; @@ -65,6 +223,9 @@ ANSI_CFG: ; ; 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. + LD B,BF_VDAQRY ; FUNCTION IS QUERY LD HL,0 ; WE DO NOT WANT A COPY OF THE CHARACTER BITMAP DATA CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION @@ -82,7 +243,33 @@ ANSI_QRY: ; ; ; -ANSI_DOCHAR: + + + ; 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 [2J + ; crtlc() uses [;<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 @@ -92,6 +279,15 @@ ANSI_DOCHAR: JR Z,ANSI_CR CP 10 ; LINEFEED JR Z,ANSI_LF + + CP 27 ; ESCAPE ; This is the hook into the escape handler + JR Z,ANSI_NOT_ESC ; go around if not CSI + LD HL,ANSI_STATE1 + LD (ANSI_STATE),HL + XOR A ; setup SUCCESS as return status + RET +ANSI_NOT_ESC: + CP 32 ; COMPARE TO SPACE (FIRST PRINTABLE CHARACTER) RET C ; SWALLOW OTHER CONTROL CHARACTERS LD B,BF_VDAWRC @@ -157,7 +353,9 @@ ANSI_XY: LD B,BF_VDASCP ; SET FUNCTIONT TO SET CURSOR POSITION 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 ; ANSI_POS: ANSI_COL .DB 0 ; CURRENT COLUMN - 0 BASED diff --git a/branches/wbw/Source/n8v.asm b/branches/wbw/Source/n8v.asm index 0e483cca..f454383a 100644 --- a/branches/wbw/Source/n8v.asm +++ b/branches/wbw/Source/n8v.asm @@ -477,10 +477,33 @@ N8V_VDASAT: N8V_VDASCO: CALL PANIC + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Video Display Processor Calculate Row Offset ; +; Enter with A = Row number (rel 0) ; +; returns with HL = offset ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +N8V_OFFSET: + PUSH DE + LD hl,row_offs ; hl -> row offset table + LD E,A ; place in LO byte of DE + LD d,0 ; make 16 bits + add hl,DE ; + add hl,DE ; hl -> word in offset table for desired row + LD e,(hl) ; pick up the LO byte of the row ptr + INC HL + ld d,(hl) ; pick up the HO byte of the ROW ptr + EX DE,HL ; hl -> offset of first column in row + POP DE + RET + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Video Display Processor Write Character ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; N8V_VDAWRC: + + LD (VDP_POS),HL ; accept curpos from caller in HL + PUSH DE LD hl,row_offs ; hl -> row offset table @@ -505,23 +528,23 @@ N8V_VDAWRC: OUT (C),a ; prime the auto incrementer OUT (C),a ; output the data byte into the name table - LD A,(VDP_COL) - INC A - LD (VDP_COL),A - CP 40 - JR NZ,N8V_VDAWRC2 - LD A,0 - LD (VDP_COL),A - LD A,(VDP_ROW) - INC A - LD (VDP_ROW),A - CP 24 - JR NZ, N8V_VDAWRC2 - ; need to scroll up one line - LD A,1 ; SCROLL ONE LINE - LD E,A ; NEEDS TO BE IN A - CALL N8V_VDASCR ; USE SCROLLING FUNCTION -N8V_VDAWRC2: +; LD A,(VDP_COL) +; INC A +; LD (VDP_COL),A +; CP 40 +; JR NZ,N8V_VDAWRC2 +; LD A,0 +; LD (VDP_COL),A +; LD A,(VDP_ROW) +; INC A +; LD (VDP_ROW),A +; CP 24 +; JR NZ, N8V_VDAWRC2 +; ; need to scroll up one line +; LD A,1 ; SCROLL ONE LINE +; LD E,A ; NEEDS TO BE IN A +; CALL N8V_VDASCR ; USE SCROLLING FUNCTION +;N8V_VDAWRC2: XOR A ; set SUCCESS return code RET ; return from HBIOS call @@ -536,52 +559,92 @@ N8V_VDAFIL: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Video Display Processor Scroll ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDASCR: - ; E = scroll distance (# lines) - LD HL,0 +; COPY DATA ZONE FROM VRAM TO SCRLBUF +VDASCR_RVRAM: + + ; CALCULATE AND SET OFFSET TO START OF DATA ZONE IN VRAM + LD A,(VDASCR_DIST) ; from number lines to scroll, + CALL N8V_OFFSET ; set HL to offset of data in name table CALL VDP_WRVRAM - LD C,DATAP - IN A,(C) ; prime autoincrement - LD HL,SCRLBUF - LD DE,24*40 + + ; SETUP FOR VRAM DATA READ + LD C,DATAP ; using the TMS9918 data port + IN A,(C) ; PRIME AUTOINCREMENT + LD HL,SCRLBUF ; DEST IS SCRLBUF OFFSET 0 + + ; COPY VDASCR_SIZE BYTES FROM VRAM TO HEAD OF SCRLBUF + LD DE,(VDASCR_SIZE) ; SIZE OF DATA ZONE N8V_VDASCR2: - IN A,(C) - LD (HL),A - INC HL - DEC DE - LD A,D - OR E - JR NZ,N8V_VDASCR2 + IN A,(C) ; FETCH NEXT BYTE FROM VRAM + LD (HL),A ; STORE IN SEQUENTIAL LOCATIONS IN SCRBUF + INC HL ; BUMP STORAGE INDEX + DEC DE ; DECREMENT BYTE COUNT REMAINING + LD A,D ; OR D + OR E ; WITH E + JR NZ,N8V_VDASCR2 ; AND DO MORE IF NOT ZERO + + RET - ; COPY UP 23 LINES - LD HL,0 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VDASCR_WVRAM: + LD HL,0 CALL VDP_WRVRAM - LD HL,SCRLBUF+40 - LD DE,(24*40)-40 - LD C,DATAP - OUT (C),A + LD C,DATAP +; OUT (C),A + LD HL,SCRLBUF + LD DE,(VDASCR_SIZE) N8V_VDASCR3: - LD A,(HL) - OUT (C),A - INC HL + LD A,(HL) ; FETCH NEXT BYTE FROM SCRLBUF + OUT (C),A + INC HL DEC DE - LD A,D - OR E - JR NZ,N8V_VDASCR3 + LD A,D + OR E + JR NZ,N8V_VDASCR3 + RET + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; BLANK LAST 40 - LD DE,40 +VDASCR_BLANKING: + ; CALCULATE SIZE OF BLANKING ZONE + LD A,(VDASCR_DIST) + CALL N8V_OFFSET + EX DE,HL ; NUMBER OF BYTES TO BLANK N8V_VDASCR4: - LD A,' ' - OUT (C),A - DEC DE - LD A,D - OR E - JR NZ,N8V_VDASCR4 - - XOR A + LD A,' ' ; WE WILL BE STORING BLANKS + OUT (C),A ; OUTPUT A BYTE TO THE VRAM NAME TABLE BLANKING ZONE + DEC DE ; DECREMENT COUNT + LD A,D ; OR THE HO BYTE + OR E ; WITH THE LO BYTE + JR NZ,N8V_VDASCR4 ; ;AND LOOP IF NOT ZERO RET + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VDASCR_DIST .DB 0 ; NUMBER OF ROWS TO SCROLL +VDASCR_SIZE .DW 0 ; SIZE IN BYTES OF DATA REGION + +N8V_VDASCR: + ; E = scroll distance (# lines) + LD A,E + LD (VDASCR_DIST),A + + LD A,(VDP_ROWS) ; NUMBER OF ROWS ON SCREEN + SUB E ; MINUS DIST IS ROWS OF DATA + CALL N8V_OFFSET ; CVT ROWS OF DATA TO NUMBER OF BYTES + LD (VDASCR_SIZE),HL ; AND SAVE FOR LATER USE + + CALL VDASCR_RVRAM ; read data region of name table into scrlbuf + + CALL VDASCR_WVRAM ; write scrlbuf to head of name table in VRAM + + CALL VDASCR_BLANKING ; blank dist lines at end of name table + + XOR A ; SET SUCCESSFUL RETURN CODE + RET ; RETURN TO CALLER + SCRLBUF .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -663,8 +726,11 @@ RECOVER: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VDP_DEVUNIT .DB 0 -VDP_ROW .DB 0 ; row number 0-23 + +VDP_POS: VDP_COL .DB 0 ; col number 0-39 +VDP_ROW .DB 0 ; row number 0-23 + VDP_ROWS .DB 24 ; number of rows VDP_COLS .DB 40 ; VDP_MODE .DB 0 diff --git a/branches/wbw/Source/tty.asm b/branches/wbw/Source/tty.asm index cefa8f39..b168e302 100644 --- a/branches/wbw/Source/tty.asm +++ b/branches/wbw/Source/tty.asm @@ -1,4 +1,5 @@ ; +; tty_dochar - added setup in HL of position data before call to write ;================================================================================================== ; TTY EMULATION MODULE ;================================================================================================== @@ -93,6 +94,9 @@ TTY_DOCHAR: JR Z,TTY_LF CP 32 ; COMPARE TO SPACE (FIRST PRINTABLE CHARACTER) RET C ; SWALLOW OTHER CONTROL CHARACTERS + + LD HL,(TTY_POS) ; physical driver needs pos data to write + LD B,BF_VDAWRC CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER LD A,(TTY_COL) ; GET CUR COL