; This program is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see . ; ; Please send your questions and comments to: ; ; Gert van der Knokke gertk@xs4all.nl ; ; Februari 2014 ; ; Monitor/loader program part originally by MarioBlunk@arcor.de ; Program is modified for 16 bit IO and lots of VGA card related ; code is added. ; ; Memory map: ; $0000-$0FFF system ROM ; $1000-$7FFF system RAM ; $8000-$FFFF banked VGA memory map (address bits A15-A19 on PIO port A0-A4) ; ; VGA memory map ; $A0000-$BFFFF display memory (in blocks of 32k at $8000-$FFFF) ; ; IO map ; $0000-$001F Z80 CTC ; $0020-$003F Z80 SIO 1 ; $0040-$005F Z80 PIO ; $0060-$007F Z80 SIO 2 ; ; $03B0-$03DF VGA IO ; ; initial VGA mode (valid are modes 00 to 3fh) STARTUPMODE equ 0 ; first VPT in BIOS rom ;STARTUPMODE equ 56 ;MODE_BASE equ VGASTART+0a41h VGASTART equ 8000h ; z80 start address of VGA segmented memory BANK_A0 equ 14h ; preset PIO outputs for VGA segment at $A0000 BANK_B0 equ 16h ; preset PIO outputs for VGA segment at $B0000 BANK_C0 equ 18h ; preset PIO outputs for VGA segment at $C0000 CH0 equ 0000h ; IO port address of CRTC timer channel 0 CH1 equ 0001h ; IO port address of CRTC timer channel 1 CH2 equ 0002h ; IO port address of CRTC timer channel 2 CH3 equ 0003h ; IO port address of CRTC timer channel 3 SIO_A_D equ 0020h ; SIO 1 A data register SIO_A_C equ 0022h ; SIO 1 A command register SIO_B_D equ 0021h ; SIO 1 B data register SIO_B_C equ 0023h ; SIO 1 B command register PIO_A_D equ 0040h ; PIO A data register PIO_A_C equ 0042h ; PIO A command register PIO_B_D equ 0041h ; PIO B data register PIO_B_C equ 0043h ; PIO B command register SIO2_A_D equ 0020h ; SIO 2 A data register SIO2_A_C equ 0022h ; SIO 2 A command register SIO2_B_D equ 0021h ; SIO 2 B data register SIO2_B_C equ 0023h ; SIO 2 B command register ; common VGA regster IO addresses CRTC equ 03d4h ; CRT controller register SEQCR equ 03c4h ; Sequencer register ATTR equ 03c0h ; Attribute Controller register GRCTR equ 03ceh ; Graphic Controller Register PEL equ 03c8h ; Palette Register FEATCTL equ 03dah ; Feature control register (write) INPUTST0 equ 03c2h ; Input Status #0 (read) INPUTST1 equ 03dah ; Input Status #1 (read) SEG_A0000 equ 0A0h/8 ; preset for segment $A0000 SEG_A8000 equ 0A8h/8 ; preset for segment $A8000 SEG_B0000 equ 0B0h/8 ; preset for segment $B0000 SEG_B8000 equ 0B8h/8 ; preset for segment $B8000 SEG_C0000 equ 0C0h/8 ; preset for segment $C0000 FONT8x14 equ 56b7h ; offset start of 8 x 14 font in BIOS rom $C0000 FONT8x8 equ 65e7h ; offset start of 8 x 8 font in BIOS rom $C0000 FONT8x16 equ 6de7h ; offset start of 8 x 16 font in BIOS rom $C0000 ;OFFSET equ 1800h ;OFFSET equ 8000h OFFSET equ 0000h BAUD2400 equ 4 BAUD9600 equ 1 RAM_BOT equ 1000h ;lowest user RAM address (4k rom) ;-------PROG START UPON SYSTEM RESET BEGIN: ------------------------------------ org 0000h WARM_START: jp init_vga ;int vectors for cmd line mode org 0Ch+OFFSET DEFW RX_CHA_AVAILABLE org 0Eh+OFFSET DEFW SPEC_RX_CONDITON ;int vectors for download mode: org 1Ch+OFFSET DEFW BYTE_AVAILABLE org 1Eh+OFFSET DEFW SPEC_BYTE_COND org 66h+OFFSET ; DEFW NMI NMI: jp INI_SYS_VAR ;handle NMI as Master Reset org 0100h BOOT: ld HL,INI_SYS_VAR ; start of monitor ld DE,7000h ; destination ld BC,INI_SYS_VAR-SYS_END ; number of bytes to go ldir ; copy block to ram jp 7000h ; continue at ram address ;------------------------------------------------------------- INI_SYS_VAR: org 7000h di ; disable interrupts (for safety) ld HL,7f80h ; init stack pointer (leave 256 bytes for vectors) ld SP,HL sub A ; ld (BLK_ERR),A ld (CMD_LEN),A ; reset CMD length counter ld (CMD_LEN+1),A ld (CMD_STS),A ; clear CMD status variable ld (RAM_DATA_STS),A ; clear RAM DATA STS ld (OUT_LEN),A ; clear STD_OUT length counter ld (OUT_LEN+1),A dec A ld (ECHO_STS),A ; set ECHO ON ;---------------------------------------------------------------------- ; now switch off rom ld BC,PIO_A_C ; select PIO A control ld A,0fh ; all outputs out (C),A ; engage... ld BC,PIO_A_D ; now set output pins (pin A7 = rom enable) ld A,00h out (C),A ; rom is switched off ; re-create the interrupt vectors in ram ld HL,RX_CHA_AVAILABLE ld (000Ch),HL ld HL,SPEC_RX_CONDITON ld (000Eh),HL ld HL,BYTE_AVAILABLE ld (001Ch),HL ld HL,SPEC_BYTE_COND ld (001Eh),HL ld HL,INI_SYS_VAR ld (0066h),HL ld A,0c3h ld (0000h),A ld HL,INI_SYS_VAR ld (0001h),HL ;-------CTC INIT begin---------------------------------------------------------------------- INI_CTC: ;init CH 1 ld A,00000011b ; int off, timer on, prescaler=16, don't care ext. TRG edge, ; start timer on loading constant, no time constant follows ; sw-rst active, this is a ctrl cmd ld BC,CH1 out (C),A ; CH1 is on hold now ;init CH0 ;CH0 provides SIO A RX/TX clock ld A,00000111b ; int off, timer on, prescaler=16, don't care ext. TRG edge, ; start timer on loading constant, time constant follows ; sw-rst active, this is a ctrl cmd ld BC,CH0 out (C),A ld A,BAUD9600 ; time constant defined out (C),A ; and loaded into channel 0 ; TO0 outputs app. 2.54MHz / 16 / (time constant) /16 ; which results in 19200 bits per sec ;-------CTC INIT done----------------------------------------------------------------------- ;-------SIO INIT begin---------------------------------------------------------------------- INI_SIO: call SIO_A_RESET ;cares for WR4,5,1 settings ;-------SIO INIT done----------------------------------------------------------------------- ;-------CPU Interrupt setup begin---------------------------------------------------------- INT_INI: ld BC,OFFSET ld A,B ld I,A ;load I reg with highbyte of OFFSET im 2 ;enable int mode 2 ;di ;no int allowed yet, will be enabled later ei ;V841 ;-------CPU Interrupt setup end------------------------------------------------------------ ;-------MENUE begin------------------------------------------------------------------------ menu: call A_RTS_ON ; ins v95/96 ld HL,Welcome ;TX welcome note call TX_STR ;call TX_STR_TERM ld HL,prompt ;TX prompt call TX_STR ; call TX_STR_TERM ;-------CMD pre processor begin------------------------------------------- CMD_pre_proc: ; call SIO_A_EI ;enable SIO_A interrupts call poll_CMD_cpl ;loop here until CMD_STS=complete ;-------CMD pre processor end---------------------------------------------- ;-------CMD post processor begin------------------------------------------- CMD_post_proc: ;verify cmd in cmd buffer against list of available cmds: ld HL,fill call PAR_CMD jp nc,l_16 call fill_mem jp EO_post_proc l_16: ld HL,copy call PAR_CMD jp nc,l_15 call req_snd ;request source, number, destination address ldir jp EO_post_proc l_15: ld HL,cmp call PAR_CMD jp nc,l_13 call req_snd ;request source, number, destination address call cmp_mem ;compare mem blocks jp EO_post_proc l_13: ; portout command ; modified for 16 bit port address l_102: ld HL,POUT call PAR_CMD jp nc,l_01 ld HL,io_adr call TX_STR ; call TX_STR_TERM call req_number ;get io address from host ld C,L ; save io L byte address in C ld B,H ; set top byte in B push BC ld HL,io_dat call TX_STR ; call TX_STR_TERM call req_number ;get io data from host pop BC ;restore io address in BC out (C),A ;output io data at io address jp EO_post_proc l_01: ld HL,PIN call PAR_CMD jp nc,l_02A ld HL,io_adr call TX_STR ; call TX_STR_TERM call req_number ;get io address from host ld C,L ; save io L byte address in C ld B,H ; set top byte in B in A,(C) push AF ;backup value input from port on stack ld HL,io_dat ;announce transmission of input value call TX_STR pop AF ;restore value input from port from stack call APP_ACCU ;append value to STD_OUT call TX_STD_OUT ;TX input value to host jp EO_post_proc l_02A: l_4: ld HL,DLD ;see comments at label l_0 and following call PAR_CMD jp nc,l_41 call req_d ;ask host for destination address ld HL,AWT_TRM call TX_STR ;request user to transmit file per xmodem ; call TX_STR_TERM call DWNLD ;download file ; call TX_STR_TERM jp EO_post_proc l_41: ld HL,HELP ;see comments at label l_0 and following call PAR_CMD jp nc,l_42 ld HL,CMD_SET call TX_STR ; call TX_STR_TERM jp EO_post_proc l_42: ld HL,EO call PAR_CMD jp nc,l_5 sub A ld (ECHO_STS),A jp EO_post_proc l_5: ld HL,VIEW_MEM ;see comments at label l_0 and following call PAR_CMD jp nc,l_8 ld HL,mem_adr16 call TX_STR ; call TX_STR_TERM call req_number ;ask host for 16 bit number call READ_MEM jp EO_post_proc l_8: ld HL,ca_usr_prg ;see comments at label l_0 and following call PAR_CMD jp nc,l_9 ld HL,mem_adr16 call TX_STR ; call TX_STR_TERM call req_number ;ask host for user program start address ld (temp0),HL ;backup start address in temp0 ld HL,l_ret ;load user program return push HL ;address on stack ld HL,(temp0) ;restore user program start address in HL jp (HL) ;jump to user program l_ret: jp EO_post_proc l_9: ;-------------------------------------------------------------- l_100: ;process any other command this way: ; call wait_2 ld HL,error ;TX "unkown cmd" call TX_STR ; call TX_STR_TERM EO_post_proc: ; call wait_2 ld HL,prompt ;TX "prompt" call TX_STR ; call TX_STR_TERM jp CMD_pre_proc ;go checking CMD_STS ;-------CMD parsing begin-------------------------------------------------- ;requires HL pointing to CMD to be parsed PAR_CMD: ld DE,CMD_PTR l_51: ld A,(DE) CPI jp nz,l_52 ;if mismatch of first char in cmd buffer, do next parsing inc DE ;prepare next char in cmd buffer cp 0Dh ;check for end of cmd (CR) jp nz,l_51 ;if end of cmd reached ;and start cmd execution: ;sending of NEW_LINE here removed with V80 scf ;if match return with carry set RET l_52: scf ccf ;if mismatch return with carry cleared RET ;-------CMD parsing end-------------------------------------------------- ;-------CMD post processor end------------------------------------------------------------------------- ;-------DOWNLOAD begin-------------------------------------------------------------------- DWNLD: ld C,0Bh ;defines timeout TICKER: call WAIT_2 dec C ld A,C cp 0 jp nz,TICKER ;------------- ;set up TX and RX: ; ld a,00110000b ;write into WR0: error reset, select WR0 ; ld BC,SIO_A_C ; out (C),A ld a,018h ;write into WR0: channel reset push BC ld BC,SIO_A_C out (C),A ld a,004h ;write into WR0: select WR4 out (C),A ld a,44h ;44h write into WR4: clkx16,1 stop bit, no parity out (C),A ld a,005h ;write into WR0: select WR5 out (C),A ld a,0E8h ;DTR active, TX 8bit, BREAK off, TX on, RTS inactive out (C),A ld a,01h ;write into WR0: select WR1 ld BC,SIO_B_C out (C),A ld a,00000100b ;no interrupt in CH B, special RX condition affects vect out (C),A ld a,02h ;write into WR0: select WR2 out (C),A ld a,10h ;write into WR2: cmd line int vect (see int vec table) out (C),A ;bits D3,D2,D1 are changed according to RX condition pop BC sub A ld (temp0),A ;reset bad blocks counter ld (RAM_DATA_STS),A ;clear RAM DATA STS ld C,1h ;C holds first block nr to expect ld HL,(DEST_ADR) ;set lower destinatiion address of user program call SIO_A_EI call A_RTS_ON call TX_NAK ;NAK indicates ready for transmission to host ;---------------------------- REC_BLOCK: ;set block transfer mode ld a,21h ;write into WR0 cmd4 and select WR1 push BC ld BC,SIO_A_C out (C),A ld a,10101000b ;wait active, interrupt on first RX character out (C),A ;buffer overrun is a spec RX condition pop BC ei ;call A_RTS_ON ; rm V95/96 halt ;await first rx char ;call A_RTS_OFF ; rm V95/96 push BC ld BC,SIO_A_C ld a,01h ;write into WR0: select WR1 out (C),A ld a,00101000b ;wait function inactive out (C),A pop BC ;check return code of block reception (e holds return code) ld a,e cp 0 ;block finished, no error jp z,l_210 cp 2 ;eot found jp z,l_211 cp 3 ;chk sum error jp z,l_613 ; call TX_NAK ;other error ? ; sub a ld a,10h ld (RAM_DATA_STS),A; set RAM DATA STS to 10h jp l_612 l_210: call TX_ACK ;when no error inc c ;prepare next block to receive sub A ld (temp0),A ;clear bad block counter jp REC_BLOCK l_211: call TX_ACK ;on eot ld A,01h ld (RAM_DATA_STS),A; set RAM DATA STS to 01h jp l_612 l_613: call TX_NAK ;on chk sum error scf ccf ;clear carry flag ld DE,0080h ;subtract 80h sbc HL,DE ;from HL, so HL is reset to block start address ld A,(temp0) ;count bad blocks in temp0 inc A ld (temp0),A cp 09h jp z,l_612 ;abort download after 9 attempts to transfer a block jp REC_BLOCK ;repeat block reception l_612: DLD_END: call SIO_A_RESET call A_RTS_ON ; in V95/96 ret ;-------Int routine upon byte available begin--------------------- BYTE_AVAILABLE: EXP_SOH_EOT: push BC ld BC,SIO_A_D in A,(C) ;read RX byte into A pop BC ; ld (7fffh),a ; debug... l_205: cp 01h ;check for SOH jp z,EXP_BLK_NR cp 04h ;check for EOT jp nz,l_2020 ld e,2h reti ;await block number EXP_BLK_NR: push BC ld BC,SIO_A_D in A,(C) ;read RX byte into A pop BC cp C ;check for match of block nr jp nz,l_2020 ;await complement of block number ld A,C ;copy block nr to expect into A CPL ;and cpl A ld E,A ;E holds cpl of block nr to expect EXP_CPL_BLK_NR: push BC ; save B (and C) ld BC,SIO_A_D ; set SIO register in A,(C) ;read RX byte into A pop BC ; get B (and C) back cp E ;check for cpl of block nr jp nz,l_2020 ;await data block ld D,0h ;start value of checksum ld B,80h ;defines block size 128byte EXP_DATA: push BC ; save B (and C) ld BC,SIO_A_D in A,(C) ;read RX byte into A pop BC ; get B (and C) back ld (HL),A add A,D ;update ld D,A ;checksum in D inc HL ;dest address +1 djnz EXP_DATA ;loop until block finished EXP_CHK_SUM: push BC ; save B (and C) ld BC,SIO_A_D ; set SIO register in A,(C) ;read RX byte into A pop BC ; get B (and C) back ; ld a,045h ;for debug only cp D ;check for checksum match jp z,l_2021 ld e,3h reti l_2020: ld E,1h RETI l_2021: ld E,0h RETI ;return when block received completely ;--------------------------- TX_NAK: ld a,15h ;send NAK 15h to host push BC ld BC,SIO_A_D out (C),A pop BC call TX_EMP RET TX_ACK: ld a,6h ;send AK to host push BC ld BC,SIO_A_D out (C),A pop BC call TX_EMP RET ;-------Int routine upon RX overflow begin--------------------- SPEC_BYTE_COND: ;in case of RX overflow ld HL,DLD_END push HL reti ;-------DOWNLOAD end---------------------------------------------------------- ;-------SIO INTERRUPT ROUTINES for cmd line mode BEGIN----------------------------------------- ;-------Int Routine upon RX charcter begin------------------------------------------------- RX_CHA_AVAILABLE: ; ei ;in V841 push AF ;backup AF ; call A_RTS_OFF ; rm V95/96 ; ld a,005h ;write into WR0: select WR5 ; out (SIO_A_C),A ; ld a,0E8h ;DTR active, TX 8bit, BREAK off, TX on, RTS inactive ; out (SIO_A_C),A push BC ld BC,SIO_A_D in A,(C) ;read RX character into A pop BC ;push AF ;backup RX character ; A holds received character ;add RX character to string in cmd buffer: ld BC,(CMD_LEN) ;BC holds current length of command ld HL,CMD_PTR ;set HL at begin of cmd buffer add HL,BC ;HL now holds pos to store RX char in ;pop AF ;restore RX char in A ld (HL),A ;write RX char where HL points to ld IY,ECHO_STS ; IY points to ECHO_STS ;examine RX character: cp 0Dh ;was last RX char a CR ? jp z,RX_CR cp 08h ;was last RX char a BS ? jp z,RX_BSP cp 7Fh ;was last RX char a DEL ? jp z,RX_BSP ;for any other character: ;if ECHO_STS=FFh TX received char back to host ; ld IY,ECHO_STS rrc (IY+0) ;each rotating of FFh sets carry jp nc,l_212 ;if ECHO_STS<>FFh don't echo an proceed at l_212 ;echo character (HL still points at char received last) push BC ld BC,SIO_A_D out (C),A ;to host pop BC call TX_EMP call RX_EMP l_212: inc BC ld (CMD_LEN),BC ;CMD_LEN holds current lenght of command ;sub A ;comm. in V841 ;ld (CMD_STS),A ;comm. in V841 ;set or leave CMD status "incomplete" ; call A_RTS_ON ;V877 jp eo_rx_cha_ava ; pop AF ; reti ;-------process cr character begin---------- RX_CR: ; call SIO_A_DI rrc (IY+0) ;each rotating of FFh sets carry jp nc,l_220 ;if ECHO_STS<>FFh don't TX line feed an proceed at l_220 ;(ECHO is ON if ECHO_STS=FFh) ld HL,NEW_LINE ;transmit new line call TX_STR ld BC,(CMD_LEN) ;TX_STR modifies BC, so restore BC from CMD_LEN l_220: ld (IN_LEN),BC ;copy CMD_LEN into IN_LEN ld A,1 ld (CMD_STS),A ;set CMD status to "complete" ; call SIO_A_DI ;disable SIO_A interrupts ;in V841 sub A ld (CMD_LEN),A ;clear CMD_LEN ld (CMD_LEN+1),A ; call A_RTS_OFF jp eo_rx_cha_ava ; pop AF ;restore AF ; reti ;leave procedure but do not enable interupts ;-------process cr character end--------------- ;-------process backspace charcter begin----------- RX_BSP: ld HL,0FFFFh add HL,BC ;carry is set if CMD_LEN>0 jp nc,END_OF_RX_BSP ;do not BACKSPACE if CMD_LEN=0 dec BC ;if CMD_LEN>0 then CMD_LEN-1 ld (CMD_LEN),BC ;update CMD_LEN ld HL,BS_SP_BS call TX_STR ; call A_RTS_ON ;V877 END_OF_RX_BSP: ;sub A ;comm. in V841 ;ld (CMD_STS),A ;comm. in V841 ;set or leave CMD status "incomplete" ; pop AF ; reti ;-------process backspace character end----------- eo_rx_cha_ava: ; call A_RTS_ON pop AF ei ; ins V95/96 reti ;-------Int Routine upon RX charcter end--------------------------------------------------- ;-------poll CMD_STS loop------------------------------ ;waits until "cmd complete" ;modifies all registers poll_CMD_cpl: ; call SIO_A_RESET ; call A_RTS_ON ; rm v95/96 l_690: ei ; call A_RTS_ON ;V877 ; rm V95/96 halt ld A,(CMD_STS) cp 1h ;poll for "cmd complete" jp nz,l_690 ; di sub A ld (CMD_STS),A ; call A_RTS_OFF ; call SIO_A_DI RET ;-------Int routine upon special RX condition begin--------------------- SPEC_RX_CONDITON: jp WARM_START ;-------Int Routine upon special RX condition end-------------------------- SIO_A_RESET: ;set up TX and RX: ld a,00110000b ;write into WR0: error reset, select WR0 push BC ld BC,SIO_A_C out (C),A ld a,018h ;write into WR0: channel reset out (C),A ld a,004h ;write into WR0: select WR4 out (C),A ld a,44h ;44h write into WR4: clkx16,1 stop bit, no parity out (C),A ld a,005h ;write into WR0: select WR5 out (C),A ld a,0E8h ;DTR active, TX 8bit, BREAK off, TX on, RTS inactive out (C),A ld a,01h ;write into WR0: select WR1 ld BC,SIO_B_C out (C),A ld a,00000100b ;no interrupt in CH B, special RX condition affects vect out (C),A ld a,02h ;write into WR0: select WR2 out (C),A ld a,0h ;write into WR2: cmd line int vect (see int vec table) ;bits D3,D2,D1 are changed according to RX condition out (C),A ld a,01h ;write into WR0: select WR1 ld BC,SIO_A_C out (C),A ld a,00011000b ;interrupt on all RX characters, parity is not a spec RX condition ;buffer overrun is a spec RX condition out (C),A pop BC SIO_A_EI: ;enable SIO channel A RX ld a,003h ;write into WR0: select WR3 push BC ld BC,SIO_A_C out (C),A ; ld a,0C1h ;RX 8bit, auto enable off, RX on ld a,0E1h ;RX 8bit, auto enable on, RX on ;v93 out (C),A pop BC ;Channel A RX active RET SIO_A_DI: ;disable SIO channel A RX ld a,003h ;write into WR0: select WR3 push BC ld BC,SIO_A_C out (C),A ; ld a,0C0h ;RX 8bit, auto enable off, RX off ld a,0E0h ;RX 8bit, auto enable on, RX off ;v93 out (C),A pop BC ;Channel A RX inactive ret A_RTS_OFF: ld a,005h ;write into WR0: select WR5 push BC ld BC,SIO_A_C out (C),A ld a,0E8h ;DTR active, TX 8bit, BREAK off, TX on, RTS inactive out (C),A pop BC ret A_RTS_ON: ld a,005h ;write into WR0: select WR5 push BC ld BC,SIO_A_C out (C),A ld a,0EAh ;DTR active, TX 8bit, BREAK off, TX on, RTS active out (C),A pop BC ret ;-------SUBROUTINES BEGIN------------------------------------------- ;-asks host for a number ;-smallest unit is BYTE (so host must send at least 2 characters) ;-half bytes are not accepted (e.g. it is invalid if host sends "123") ;-in case of invalid input a return to EO_post_proc is performed (by manipulation of stack) ! ;-does not check content of characters (e.g. result of sending "nice" is unknown) ;-the result of the last 2 characters in this number is returned in A ;-the result of the last 4 characters in this number is returned in HL, wherein H holds high ; byte and L holds low byte: ; (e.g. sending "123456" returns A holding 56h, and HL holding 3456h) ; all other characters get lost ;-modifies all registers except the background registers ;-loads every converted byte into long number storage (lowbyte at lowest address) req_number: ;call set_CMD_incpl ;clear CMD status ;comm. V841 ;call SIO_A_EI ;ei ;comm. V841 call poll_CMD_cpl ld A,(IN_LEN) ;get lowbyte of IN_LEN srl A ;divide by 2 / A holds number of words in input buffer ld B,A ;copy into B jp nc,l_133 ;if IN_LEN was odd ld HL,error ;TX ..? call TX_STR ld HL,EO_post_proc ;replace return address on stack by address of EO_post_proc inc SP inc SP push HL ret ;and return l_133: ld DE,CMD_PTR ld IX,NUMBER ;IX points to beginning of long number storage l_132: push BC ;backup number of words on stack call conv_RX_2ASC2BIN;convert word in input buffer to byte , DE points to word ;A holds result ld (IX+0),A ;load A into long number storage inc IX ;advance pointer of long number storage by 1 inc DE ;advance DE by two inc DE ;so that it point to next word in input buffer pop BC ;restore number of words from stack bit 0,B ;check for last cycle: bit 0 of counter is set in last cycle jp nz,l_135 ld H,A l_135: djnz l_132 ;loop to l_132 until all words are read from buffer ld L,A ret ;return ;----------------------------------------------------- TX_STD_OUT: ld HL,STD_OUT call TX_STR ; call TX_STR_TERM ret TX_STR: ;TX string, HL points to first byte address ;modifies A, HL TX_CHA: ld a,(HL) push BC ld BC,SIO_A_D out (C),A pop BC call TX_EMP ; call host_rdy sub a cpi ;look for string termination character 0h jp nz,TX_CHA ld (OUT_LEN),A ;set output string length lowbyte to 0 ld (OUT_LEN+1),A ;set output string length highbyte to 0 ret TX_EMP: ; check for TX buffer empty ;modifies A sub a ;clear a, write into WR0: select RR0 inc a ;select RR1 push BC ld BC,SIO_A_C out (C),A in A,(C) ;read RRx pop BC bit 0,A jp z,TX_EMP ret RX_EMP: ; check for RX buffer empty ;modifies A sub a ;clear a, write into WR0: select RR0 push BC ld BC,SIO_A_C out (C),A in A,(C) ;read RRx pop BC bit 0,A ret z ;if any rx char left in rx buffer push BC ld BC,SIO_A_D in A,(C) ;read that char pop BC jp RX_EMP ;-------delay---------------- WAIT_2: ; delay push AF push BC push DE ld de,0500h l_W20: djnz l_W20 dec de ld a,d or a ;update zero flag jp nz,l_W20 pop DE pop BC pop AF ret ;-------convert 2 received ASCII char to byte begin----------------------------- ; DE points to input in CMD_PTR and CMD_PTR+1 ; output in A ; modifies A, B conv_RX_2ASC2BIN: ;ld DE,CMD_PTR ;read first char in cmd buffer push DE ;came with V783 ld A,(DE) bit 6,A jp z,hi_ni_09 ;if bit 6 not set,it's below Ah add A,9h jp sh_4xl hi_ni_09: sub 30h ;convert to 4 bit number sh_4xl: sla A sla A sla A sla A ld B,A ;B[7..4] hold high nibble inc DE ;read 2nd char in cmd buffer ld A,(DE) bit 6,A jp z,lo_ni_09 ;if bit 6 not set,it's below Ah add A,9h and 0Fh jp EO_conv_RX_2ASC2BIN lo_ni_09: sub 30h ;convert to 4 bit number EO_conv_RX_2ASC2BIN: or B ;A holds result pop DE ;came with V783 RET ;-------convert 2 received ASCII char to byte end---------------------------- ;-------convert byte to 2 ASCII char begin--------------------------- ; input value in A ; output high nibble in D, low nibble in C ; modifies A,BC,D conv_BYTE2ASC: ld C,A ;backup given byte in C proc_hi_ni: ;process high nibble and 0F0h ;clear low nibble srl A ;move high nibble into low nibble srl A srl A srl A ld B,A ;backup A in B ld A,9 sub B jp c,ni_AF ;nibble > 9 ? ld A,B ;restore nibble add A,30h ;add 30h to make ASCII char jp hi_ni_rdy ni_AF: ld A,B ;restore nibble add A,37h ;add 40h-9h to make ASCII char hi_ni_rdy: ld D,A ;high nibble ready in D ;process low nibble ld A,C ;restore given byte from C and 0Fh ;clear high nibble ld B,A ;backup A in B ld A,9 sub B jp c,ni_AF2 ;nibble > 9 ? ld A,B ;restore nibble add A,30h ;add 30h to make ASCII char jp lo_ni_rdy ni_AF2: ld A,B ;restore nibble add A,37h ;add 40h-9h to make ASCII char lo_ni_rdy: ld C,A ;low nibble ready in C ;high nibble ready in D RET ;-------convert byte to 2 ASCII char end--------------------------- ;-------------------------------------------------------------------------- APP_ACCU: ;converts A content into 2 ASCII characters in C and D ;C holds low nibble, D holds high nibble ;appends characters in C and D to STD_OUT ;appends 0h as string termination ;increments OUT_LEN by two ;modifies A,BC,DE,IX,IY call conv_BYTE2ASC ;converts A to 2xASCII chars in D and C ld B,C ld C,D ;high nibble in C, low nibble in B scf ;set carry flag APP_CHAR: ;requires char to append in C ;returns at label l_933 if carry not set push AF ;backup carry status ld IX,STD_OUT ;IX points to STD_OUT begin ;ld A,(OUT_LEN) ;get current output string length ld DE,(OUT_LEN) ;get current output string length ld IY,OUT_LEN ;IY points to OUT_LEN ;ld D,0h ;ld E,A add IX,DE ;IX points to last pos in string ld (IX+0),C ;append C to string inc (IY+0) ;OUT_LEN+1 ld (IX+1),0h ;append termination string pop AF ;restore carry status l_933: ret nc ;return if carry not set ld (IX+1),B ;else append B to string (overwrite former termination) inc (IY+0) ;OUT_LEN+1 ld (IX+2),0h ;append termination to string RET ;--------------------------------------------------------------------- READ_MEM: ;reads memory content starting where HL points to ;transmits row by row, so STD_OUT holds max. 52d characters ;modifies all registers ! ld B,10h ;read 16 lines RD_HL_ROW: push BC ;load first address of first row in STD_OUT ld A,H ;append high byte of mem address EXX ;backup HL in background register call APP_ACCU EXX ;restore HL from background register ld A,L ;append low byte of mem address EXX ;backup HL in background register call APP_ACCU scf ;add space character ccf ld C,020h call APP_CHAR EXX ;restore HL from background register ;first address of first row ready in STD_OUT ld B,10h ;read 16 columns RD_HL_COL: ld A,(HL) ;read memory content into A EXX ;backup HL in background register call APP_ACCU scf ;append space character ccf ld C,020h call APP_CHAR EXX ;restore HL from background register inc HL ;HL points to next mem position djnz RD_HL_COL ;loop until 16 columns are read EXX ;backup HL in background register call TX_STD_OUT ;TX row to host ld HL,NEW_LINE ;transmit new line call TX_STR EXX ;restore HL from background register pop BC ;restore BC from stack djnz RD_HL_ROW ;loop until 16 rows are read ret ;---------------------------------------------------------------------------- div_by_2: ;divides content of BC by 2 ;writes the result back into BC ! ;modifies BC srl B jp c,l_713 srl C ret l_713: srl C set 7,C ret ;---------------------------------------------------------------------------- TX_NUMBER: ;transfers long number to host ;HL points to low byte of number ;BC holds number of bytes ;modifies A, HL, BC add HL,BC l_844: dec HL ;HL points to high byte of number ld A,(HL) push BC call APP_ACCU ;append byte to STD_OUT pop BC dec BC ;number of bytes - 1 ld A,B cp 0 ;test high byte of BC for 0 jp nz,l_844 ;if yes, ld A,C cp 0 ;test low byte of BC for 0 jp nz,l_844 ;if yes, call TX_STD_OUT ;TX input value to host ret ;----------------------------------------------------------------------------- req_snd: ;requests source, number, destination address ld HL,source16 call TX_STR ; call TX_STR_TERM call req_number ;get source address from host ld (SOURCE_ADR),HL req_nd: ld HL,count16 call TX_STR ; call TX_STR_TERM call req_number ;get number of bytes to burn from host ld (NUMB_OF_BYTES),HL req_d: ld HL,destin16 call TX_STR ; call TX_STR_TERM call req_number ;get destination address from host ld (DEST_ADR),HL ;prepare block transfer and search commands like ldi, cpi, cpir, ldir ld HL,(SOURCE_ADR) ld DE,(DEST_ADR) ld BC,(NUMB_OF_BYTES) ret fill_mem: ld HL,new_dat call TX_STR ; call TX_STR_TERM call req_number ;get fill value from host ld (SCRATCH),A ;save fill value in scratch call req_nd ;request number, destination address ld DE,(DEST_ADR) ld BC,(NUMB_OF_BYTES) l_fi0: ld HL,SCRATCH ;set source pointer to scratch ldi ;copy fill value (from scratch) to destination address jp pe,l_fi0 ;loop until block filled ret cmp_mem: ;ld HL,(SOURCE_ADR) ;ld DE,(DEST_ADR) ;ld BC,(NUMB_OF_BYTES) l_cmp0: ld A,(DE) ;load data at dest. address into A ld (SCRATCH),A ;place copy of data in scratch cpi ;cmp data at source address with data at dest. addr. jp nz,l_cmp_err inc DE ;advance dest. pointer jp pe,l_cmp0 ;loop until byte counter bc is 0 ret l_cmp_err: dec HL ;set source pointer back at address where error occured push HL ;save current source address push DE ;save current dest. address ld HL,error ;tx "..?" call TX_STR ld HL,at ;tx "at" call TX_STR pop DE ;restore current dest. address ld A,D push DE call APP_ACCU pop DE ld A,E call APP_ACCU call TX_STD_OUT ;tx current dest. address to host ld HL,expect ;tx "exp:" to host call TX_STR pop HL ;restore current source address ld A,(HL) call APP_ACCU call TX_STD_OUT ;tx current source address to host ld HL,read ;tx "read:" call TX_STR ld A,(SCRATCH) ;restore from scratch data read at dest. address call APP_ACCU call TX_STD_OUT ;tx corrupted data to host ret reg_dump: ;backup registers in bak_xx push HL ld (bak_hl),HL push AF pop HL ld (bak_af),HL ; push BC ; pop HL ld (bak_bc),BC ; push DE ; pop HL ld (bak_de),DE ; push IX ; pop HL ld (bak_ix),IX ; push IY ; pop HL ld (bak_iy),IY push IY push IX push DE push BC push AF call l_rd3 ;make newline ld HL,reg_af ;announce transmission of AF call TX_STR pop AF ;restore value input from port from stack push AF call APP_ACCU ;append value to STD_OUT pop BC call l_rd1 ld HL,reg_bc ;announce transmission of BC call TX_STR pop AF ;restore value input from port from stack push AF call APP_ACCU ;append value to STD_OUT pop BC call l_rd1 ld HL,reg_de ;announce transmission of DE call TX_STR pop AF ;restore value input from port from stack push AF call APP_ACCU ;append value to STD_OUT pop BC call l_rd1 ld HL,reg_ix ;announce transmission of IX call TX_STR pop AF ;restore value input from port from stack push AF call APP_ACCU ;append value to STD_OUT pop BC call l_rd1 ld HL,reg_iy ;announce transmission of IY call TX_STR pop AF ;restore value input from port from stack push AF call APP_ACCU ;append value to STD_OUT pop BC call l_rd1 ld HL,reg_hl ;announce transmission of HL call TX_STR pop AF ;restore value input from port from stack push AF call APP_ACCU ;append value to STD_OUT pop BC call l_rd1 ;get return address ; pop DE pop HL ld (bak_pc),HL push HL ; push DE ld HL,reg_pc ;announce transmission of PC call TX_STR ld HL,(bak_pc) ld A,H call APP_ACCU ;append value to STD_OUT ld HL,(bak_pc) ld A,L call l_rd2 ld HL,reg_sp ;announce transmission of SP call TX_STR ld (bak_sp),SP ld HL,(bak_sp) ; inc HL ; inc HL inc HL inc HL ld (bak_sp),HL ;correct bak_sp to value previous to register_dump call ld A,H call APP_ACCU ;append value to STD_OUT ld HL,(bak_sp) ld A,L call l_rd2 ld HL,reg_ir ;announce transmission of IR call TX_STR ld A,I call APP_ACCU ;append value to STD_OUT ld A,R call l_rd2 ;restore registers ld BC,(bak_bc) ld DE,(bak_de) ld IY,(bak_ix) ld IX,(bak_iy) ld HL,(bak_af) push HL pop AF ld HL,(bak_hl) ret l_rd1: ld a,c l_rd2: call APP_ACCU ;append value to STD_OUT call TX_STD_OUT ;TX input value to host l_rd3: ld HL,NEW_LINE ;transmit new line call TX_STR ret ; ================================================================================================================== ; additional code for VGA subsystem init_vga: ; enable subsystem ld A,18h ld BC,46e8h out (C),A ; enable extensions ld A,06h ld BC,SEQCR ; $03C4 Sequencer register out (C),A ld A,81h inc C out (C),A ; enable video subsystem ld A,01h ld BC,03c3h out (C),A ; assert reset ld BC,SEQCR ; $03C4 Sequencer register ld A,00h out (C),A ld A,00h inc C out (C),A nop nop ; release reset ld BC,SEQCR ; $03C4 Sequencer register ld A,00h out (C),A ld A,03h inc C out (C),A ; read the 'Eagle ID' needed to enable extensions ld A,0ch ; screen start Hi (must be cleared to read ID) ld BC,CRTC ;$03D4 CRT controller out (C),A inc C ld A,00h out (C),A ld A,1fh ; read 'Eagle ID' ld BC,CRTC ; $03D4 CRT controller out (C),A inc C in A,(C) ld E,A ; save ID in E ld A,06h ; address extensions register ld BC,SEQCR ; $03C4 Sequencer register out (C),A ld A,E ; get 'Eagle ID' from E inc C out (C),A ; write back ld A,STARTUPMODE ; start in this mode call set_mode call init_font ; preset font call init_feat ; handle feature bits and enable video out ; VGA init is done now, screen should be clear jp BOOT init_feat: ; init feature control register (DAC bits 6 and 7 are 'float' when not initialized) ld BC,FEATCTL ; $03DA Feature Control register ld A,10000000b ; top bit connects DAC inputs 6 and 7 to system out (C),A ld BC,46e8h ; disable SETUP bit ld A,08h out (C),A call init_pal ; init palette ; enable video out (extensions register) ld BC,SEQCR ; $03C4 Sequencer register ld A,83h out (C),A inc C ld A,20h out (C),A ; now fill video memory with characters ld A,SEG_B8000 ; select $B8000 as segment call set_seg ret ; init VGA controller for mode 'A' using VPT tables set_mode: ; push AF ; and 01h ; limit modes to 0 and 1 ; ld (GRAPHTEXT),A ; store current mode (0=text, else graphic) ; ld A,SEG_C0000 ; call set_seg ; point to BIOS rom ld HL,MODE_BASE ; start of first mode VPT ; ld DE,40h ; offset ; pop AF ; get mode back ; call fastmul ; calculate offset based on mode number ld A,(HL) ; get number of columns for this mode ld (columns),A ; store inc HL ; advance ld A,(HL) ; get number of rows for this mode ld (rows),A ; store inc HL ; advance ld A,(HL) ; get number of scanlines per character ld (scanlines),A ; store inc HL ; advance ld A,(HL) ; get page length (low byte) ld (pagelength),A ; store inc HL ; advance ld A,(HL) ; get pagelength (high byte) ld (pagelength+1),A ; store inc HL init_sequencer: ; init sequencer registers for mode ; HL should be pointing to the first sequencer register value ld D,01h seq1: ld A,D cp 05h ; end of registers jp z,seq_done ld BC,SEQCR ; $03C4 Sequencer register out (C),A ; output index inc C ld A,(HL) ; get value from table out (C),A ; store inc D ; next... inc HL jp seq1 seq_done: ; some misc. registers settings for the CL-GD410 ld BC,03c2h ; set clock source, sync polarity etc. ; ld A,11000011b ; -H -V PB=0 DVD=0 CS=00b ER=1 IOA=1 ld A,(HL) ; Hl should be pointing to the misc register setting out (C),A ld BC,SEQCR ; $03C4 Sequencer register ld A,0a4h ; clock select register out (C),A inc C ld A,(HL) ; get MISC register setting back and 0ch ; keep clock bits or 10h ; select VGA clocks ; ld A,00010100b ; extended clock select (bits 2,3 and 4 seem to respond) ; bit 4 3 2 ; 0 0 0 14 MHz (EGA) ; 0 0 1 16 MHz (EGA) ; 0 1 0 25 MHz/feature connector ; 0 1 1 32 MHz ? ; 1 0 0 25 MHz (VGA) ; 1 0 1 28 MHz (VGA) ; 1 1 0 20 MHz (LCD) ; 1 1 1 40 MHz (LCD) out (C),A inc HL init_crtc: ; init CRTC registers for mode ; HL should be pointing to the first value for the CRTC registers ld D,00h crtc1: ld A,D cp 19h ; end of registers jr z,crtc_done ld BC,CRTC ; $03D4 CRT controller out (C),A ; output index inc C ld A,(HL) ; get value from table out (C),A ; store inc D ; next... inc HL jr crtc1 crtc_done: init_attr: ; init attribute controller registers for mode ld BC,FEATCTL ; $03DA Feature Control register ; reset attribute flipflop in A,(C) ; HL should be pointing to the start of the attribute values ld D,00h attr1: ld A,D cp 14h ; end of registers jr z,attr_done ld BC,ATTR ; $03C0 Attribute Controller register out (C),A ; output index ;inc C ; no! ld A,(HL) ; get value from table out (C),A ; store (in same IO address!) ; call hexstring inc D ; next... inc HL jr attr1 attr_done: init_gcr: ; init graphic controller registers for mode ld D,00h gcr1: ld A,D cp 09h ; end of registers jr z,gcr_done ld BC,GRCTR ; $03CE Graphic Controller register out (C),A ; output index inc C ld A,(HL) ; get value from table out (C),A ; store ; call hexstring inc D ; next... inc HL jr gcr1 gcr_done: ret ; init palette first 16 colors init_pal: ld BC,03c6h ; set mask to $FF ld A,0ffh out (C),A ld E,16 ; repeat palette setting for 16 colors pal2: ld HL,pal_16c ; pointer to palette values ld BC,PEL ; $03C8 Palette register (write) ld A,00h ; first palette start address out (C),A ; set inc C ; point BC to PEL data register ld D,16 ; counter fo 16 colors pal1: ld A,(HL) ; get R value out (C),A inc HL ld A,(HL) ; get G value out (C),A inc HL ld A,(HL) ; get B value out (C),A inc HL dec D ld A,0h cp D jr nz,pal1 dec E ld A,00h cp E jr nz,pal2 ret ; copy font from rom to ram init_font: call fmapon ; select font mapping ; find out what font we need to install ld A,(scanlines) ; 8 pixel font ? cp 8 ; 8x8 ? jp nz,font4 ; nope ld HL,FONT8x8+VGASTART jr font7 font4: ; 14 pixel font ? cp 14 ; 14x8 ? jr nz,font5 ; nope ld HL,FONT8x14+VGASTART jr font7 font5: ; all other modes get 16 pixel font ld HL,FONT8x16+VGASTART font7: ld DE,VGASTART ; offset in VRAM destination in Z80 space ld C,00h ; 256 characters to go font2: ld A,(scanlines) ; number of scanlines per character to copy ld B,A ; store in B font1: ; copy a byte from Bios rom to VGA ram segment ; ; set high address lines to access $C0000 region (source) ld A,SEG_C0000 call set_seg ld A,(HL) ; get byte push AF ; save A on stack ; set high address lines to access $A0000 region (destination) ld A,SEG_A0000 call set_seg pop AF ; get A back ld (DE),A ; store in VGA ram inc HL ; increment pointers inc DE ; HL and DE djnz font1 ; decrement B ; fill up to 32 scanlines ld A,(scanlines) ld B,A ; setup 'scanlines' dummy bytes font3: ; skip 'n' bytes (VGA font is always 8x32 bytes per character!) inc DE ld (DE),A inc B ld A,32 cp B jr nz,font3 dec C ; cp C ; A is still zero jr nz,font2 ; ret jp fmapoff ; restore mapping and return ; set VGA registers for font mapping fmapon: ;map VGA memory to 0A0000h ld BC,GRCTR ; $03CE Graphic Controller register ld A,06h out (C),A inc C in A,(C) ; get mapping ld (oldmap),A ; save old mapping ld A,04h out (C),A ;select only bitplane 2 ld BC,SEQCR ; $03C4 Sequencer register ld A,02h out (C),A inc C ld A,04h out (C),A ret fmapoff: ;map VGA memory back to previous setting ld BC,GRCTR ; $03CE Graphic Controller register ld A,06h out (C),A inc C ld A,(oldmap) ; get mapping back out (C),A ; done ret ; set top 5 address lines in PIO A to adjusted segment value in A (rom only mode) set_seg: push BC ld BC,PIO_A_D or 128 ; keep ROM enabled for now out (C),A ; set them output bits pop BC ret MODE_BASE: ; mode 56 modified for linear access as my new mode 0: ; text mode 80x25 with 16 colors ; character plane is plane 0 ; attribute plane is plane 1 ; font plane is plane 2 ; plane 3 is free to use (64k max) defb 80 ; columns defb 24 ; rows (-1) defb 16 ; scanlines per character defw 4096 ; page length defb 01h,03h,00h,06h ; sequencer registers $3c4 defb 67 ; misc register ; crtc registers $03d4 defb 062h defb 04fh defb 055h defb 022h defb 056h defb 002h defb 0c1h defb 01fh defb 000h defb 04fh defb 00dh defb 00eh defb 000h defb 000h defb 000h defb 000h defb 09ch defb 02eh defb 08fh defb 028h defb 01fh defb 09ch defb 0b3h defb 0e3h ; modified defb 0ffh ; attribute registers $03c0 defb 00h ; 00 palette register defb 01h defb 02h ; ... defb 03h defb 04h defb 05h defb 06h ; ... defb 07h defb 08h defb 09h defb 0ah defb 0bh ; ... defb 0ch defb 0dh defb 0eh defb 0fh ; 0f palette register defb 0ch ; 10 mode control register defb 00h ; 11 overscan color register defb 0Fh ; 12 color plane enable register defb 08h ; 13 horizontal panning register ; graphic controller $03ce defb 000h defb 000h defb 000h defb 000h defb 000h defb 000h ; 010h defb 00ch ; 00eh defb 000h defb 0ffh ; sixteen color palette pal_16c: defb 1,1,1 ; black defb 1,1,32 ; blue defb 1,32,1 ; green defb 1,32,32 ; cyan defb 32,1,1 ; red defb 32,1,32 ; magenta defb 16,16,1 ; brown defb 32,32,32 ; light grey defb 16,16,16 ; dark grey defb 1,1,63 ; light blue defb 1,63,1 ; light green defb 1,63,63 ; light cyan defb 63,1,1 ; light red defb 63,1,63 ; light magenta defb 63,63,1 ; yellow defb 63,63,63 ; white ;-------TEXT BEGIN--------------------------------------------------- Welcome: DEFB 0Ch ;CLS DEFM 'KGE Z80 VGA v0.1 ready' ;sys version DEFB 0 prompt: DEFB 0Ah ;next line DEFB 0Dh ;cursor home DEFM 'cmd> ' DEFB 0 reg_af: DEFM 'AF: ' DEFB 0 reg_bc: DEFM 'BC: ' DEFB 0 reg_de: DEFM 'DE: ' DEFB 0 reg_hl: DEFM 'HL: ' DEFB 0 reg_ix: DEFM 'IX: ' DEFB 0 reg_iy: DEFM 'IY: ' DEFB 0 reg_pc: DEFM 'PC: ' DEFB 0 reg_sp: DEFM 'SP: ' DEFB 0 reg_ir: DEFM 'IR: ' DEFB 0 error: DEFM '...?' DEFB 0 mem_adr16: DEFM 'mem_adr: ' DEFB 0 source16: DEFM 'source_adr: ' DEFB 0 destin16: DEFM 'destination_adr: ' DEFB 0 count16: DEFM 'number_of_bytes: ' DEFB 0 new_dat: DEFM 'new_dat: ' DEFB 0h AWT_TRM: DEFM 'please send file via xmodem !' DEFB 0h io_adr: DEFM 'io_addr: ' DEFB 0h io_dat: DEFM 'io_data: ' DEFB 0h at: DEFM ' at: ' DEFB 0h expect: DEFM ' expected: ' DEFB 0h read: DEFM ' read: ' DEFB 0h pio_ab: DEFM 'PIO A/B...' DEFB 0h NEW_LINE: DEFB 0Dh ;next line DEFB 0Ah ;cursor home DEFB 0 BS_SP_BS: DEFB 08h ;BSP DEFB 20h ;SPACE DEFB 08h ;BSP DEFB 0 2xBS: DEFB 08h ;BSP DEFB 08h ;BSP DEFB 0 ;-------COMMAND SET begin---------------------------------------- HELP: DEFM 'help' DEFB 0Dh CMD_SET: POUT: DEFM 'portout' DEFB 0Dh ;cursor home DEFB 0Ah ;next line PIN: DEFM 'portin' DEFB 0Dh ;cursor home DEFB 0Ah ;next line VIEW_MEM: DEFM 'viewmem' DEFB 0Dh ;cursor home DEFB 0Ah ;next line cmp: DEFM 'comp' DEFB 0Dh ;cursor home DEFB 0Ah ;next line copy: DEFM 'copy' DEFB 0Dh ;cursor home DEFB 0Ah ;next line fill: DEFM 'fill' DEFB 0Dh ;cursor home DEFB 0Ah ;next line DLD: DEFM 'load' DEFB 0Dh ;cursor home DEFB 0Ah ;next line ca_usr_prg: DEFM 'call' DEFB 0Dh ;cursor home DEFB 0Ah ;next line EO: DEFM 'echooff' DEFB 0Dh ;cursor home DEFB 0Ah ;next line CMDs_END: DEFB 0h posx defs 1 ; cursor X posy defs 1 ; cursor Y gposx defs 2 ; graphics origin X gposy defs 2 ; graphics origin Y gcol defs 1 ; graphics color gbcol defs 1 ; graphic background color gmode defs 1 ; graphic mode oldchar defs 1 ; VDU command if queue is done GRAPHTEXT defs 1 ; flag for graphic or text mode scanlines defs 1 ; temp storage for number of scanlines per character for current mode columns defs 1 ; temp storage for number of columns for current mode rows defs 1 ; temp storage for number of rows for current mode pagelength defs 2 ; temp storage for pagelength for current mode dx defs 2 ; storage for DX dy defs 2 ; storage for DY grseg defs 1 ; current graphic segment grchar defs 1 ; graphic character VDUQPNT defs 1 ; vdu queue pointer CURATTR defs 1 ; current attribute oldmap defs 1 ; storage for vga mapping oldseq defs 1 ; store for sequencer setting RAM_DATA_STS defs 1 ;holds 1 after successful download in RAM area SCRATCH defs 1 ;used by various functions CMD_STS defs 1 ;holds status of cmd. 0=incomplete, 1=complete PIO_A_MODE defs 1 ;holds current PIO A mode PIO_A_IO_CONF defs 1 ;holds current IO configuration of PIO A PIO_B_MODE defs 1 ;holds current PIO B mode PIO_B_IO_CONF defs 1 ;holds current IO configuration of PIO B RAM_TOP defs 2 NUMB_OF_BYTES defs 2 ; number of bytes SOURCE_ADR defs 2 ; source address DEST_ADR defs 2 ; destination address OUT_LEN defs 2 ;holds length of output buffer (lowbyte) ECHO_STS defs 2 ;holds FFh if echo enabled, 0h if echo disabled temp0 defs 2 ;used by various functions, holds number of ;unsuccessful block transfers/block during download CMD_LEN defs 2 ;holds actual length of cmd in cmd buffer (lowbyte) ;holds actual length of cmd in cmd buffer (highbyte) IN_LEN defs 2 ;holds length of of last cmd in input buffer (lowbyte) ;holds length of of last cmd in input buffer (highbyte) CMD_PTR defs 20h ;start pos where cmd buffer begins, RX char become appended ;req_number converts cmd buffer to integer NUMBER (see below) ;max 32d characters allowed ;so value in NUMBER may be as large as 16x8bit=128bit STD_OUT defs 20h ;start pos where TX chars are stored and appended, max 64d char ;used for backup in function "register dump": ;v93 bak_af defs 1 bak_bc defs 1 bak_de defs 1 bak_hl defs 1 bak_ix defs 1 bak_iy defs 1 bak_pc defs 1 bak_sp defs 1 NUMBER defs 1 ;start pos of long number storage ;no protection agains stack corruption ! ;stack defaults to 1800h upon system start ;------------------------------------------------------------------------------- SYS_END: