; *********************************************** ; * * ; * SET.ASM * ; * AMPRO Little Board * ; * Serial/Parallel Port Setup Utility * ; * * ; * Copyright (C) 1985, AMPRO Computers Inc. * ; * * ; *********************************************** ; Version 1.0 - 15 June 85 - Initial release (fsw) ; VERS EQU 10 ; ver 1.0 ; ; SET.ASM will allow the system communication prameters to be ; changed from the command line. All changes will be in memory ; resident bios and will not modify the disk as in CONFIG.COM. ; Commands are in the following format and variations. ; ; SET TERMINAL=PORT A ; SET TERMINAL=PORT B ; SET PRINTER=PORT A ; SET PRINTER=PORT B ; SET PRINTER=PARALLEL ; SET PORT A=9600,8,A,N,Y ; ^ ^ ^ ^ ^ ; | | | | Hand shake (Y)es or (N)o ; | | | Parity (O)dd,(E)ven,(N)one ; | | Stop bits (A=1,B=1.5,C=2) ; | Data bits (5,6,7,8) ; Baud rate (110,300,450,600,1200,2400,4800,9600,19.2,38.4) ; SET PORT B=same as port A (no 19.2,38.4 baud) ; SET ? show current prameters ; ; ----------------------------------------------------------------------- ; ; ascii equates ; LF EQU 0AH ; line feed CR EQU 0DH ; carriage return SPC EQU 20H ; space ESC EQU 1BH ; ; cp/m equates ; BDOS EQU 05H ; bdos entry point BIOS EQU 01H ; address of warm boot in bios FCN EQU 5CH ; default fcn CMDTAL EQU 80H ; location of command tail WMBOOT EQU 00H ; jmp to warm boot TPA EQU 100H ; start of tpa ; ORG TPA ; start of tpa ; START: LXI H,0 DAD SP ; hl=ccp stack pointer SHLD RETURN ; save ccp stack pointer LXI SP,STACK CALL CLRSCN ; clear screen CALL ILPRT DB ' AMPRO Serial/Parallel Port Setup Utility' DB ' (ver ',VERS/10+'0','.',VERS MOD 10+'0',')',cr,lf DB ' Copyright (C) 1985 - AMPRO Computers, Inc.',cr,lf,0 LDA CMDTAL ; see if entry on command line ORA A ; zero ? JNZ BEGIN ; ; START1: CALL ILPRT ; DB cr,lf,0 START2: CALL ILPRT DB 'No command given. SET command choices are:',cr,lf,lf DB ' SET TERMINAL=PORT A or PORT B',cr,lf,lf DB ' SET PRINTER=PORT A, PORT B, or PARALLEL',cr,lf,lf DB ' SET PORT A=9600,8,A,N,Y',cr,lf DB ' | | | | |',cr,lf DB ' | | | | Hardware Hand shake: (Y)es or (N)o',cr,lf DB ' | | | Parity: (O)dd,(E)ven,(N)one',cr,lf DB ' | | Stop bits: (A)=1,(B)=1.5,(C)=2',cr,lf DB ' | Data bits: (5),(6),(7),(8)',cr,lf DB ' Baud rate: (110),(300),(450),(600),(1200),',cr,lf DB ' (2400),(4800),(9600),(19200),(38400)',cr,lf,lf DB ' SET PORT B=same as port A (no 19200,38400 baud)',cr,lf,lf DB ' SET ? --> to display current settings',cr,lf,0 ; JMP EXIT ; BEGIN: CALL GETBIO ; get current system parameters LXI H,CMDTAL BEG1: INX H ; point to begining of command input MOV A,M CPI SPC ; skip the spaces JZ BEG1 ANA A ; end of command line=0 JZ START1 ; had just spaces, give message and exit XCHG ; 'de'=start of command CALL COMPARE DB 'PORT A',0 ; set port A JNC PORTA CALL COMPARE DB 'PORT B',0 ; set port B JNC PORTB CALL COMPARE DB 'PRINTER',0 ; printer JNC PRN CALL COMPARE DB 'TERMINAL',0 JNC TERM ; set terminal port CALL COMPARE DB '?',0 ; give current system parameters JNC NOW JMP BDEXIT ; no match, exit ; ; ; set terminal to port a or b ; TERM: CALL DELIM ; get position of subcmd JC BDEXIT ; was none XCHG ; address of subcmd in 'de' CALL COMPARE DB 'PORT A',0 MVI B,01H ; con:=crt: JNC PTA CALL COMPARE DB 'PORT B',0 MVI B,00H ; con:=tty: JC BDEXIT ; PTA: LDA IOBYT ; get i/o byte ANI 0FCH ; mask con: bits ORA B ; or new con: bits STA IOBYT ; save JMP GOODEX ; ; ; set up the ports ; PORTB: MVI A,0AH ; offset in dart table STA PORT JMP PORTC ; ; PORTA: XRA A ; clear a STA PORT ; set work value to port A PORTC: CALL DELIM ; find the delimeter '=' JC BDEXIT ; ??????????????????? CALL GETSPD ; get speed, set ctc ; ; do the rest ; PORTD: CALL GETNXT ; get the next option MVI A,'5' CMP M JZ BIT5 ; 5 data bits INR A CMP M JZ BIT6 ; 6 data bits INR A CMP M JZ BIT7 ; 7 data bits INR A CMP M JNZ BDEXIT ; if bad input no changes made MVI A,60H ; word length=8 JMP SETWR5 ; BIT5: XRA A ; word length=5 JMP SETWR5 ; BIT6: MVI A,40H ; word length=6 JMP SETWR5 ; BIT7: MVI A,20H ; word length=7 ; SETWR5: PUSH PSW ; save 'a' MVI A,60H ; clear word length MVI B,3 ; offset to wr5 CALL CLRWR ; clear word length bits POP PSW ; get 'a' PUSH PSW ; and save again ORA M ; or in the new value MOV M,A ; new value to wr5 ; MVI A,0C0H ; do wr3 also, mask value MVI B,5 ; offset to wr3 CALL CLRWR POP PSW ; get bits back RLC ; rotate bits into position ORA M MOV M,A ; new value in wr3 ; ; stop bits 1,1.5,2 ? ; STPBIT: LHLD TEMP0 ; where we are on the command line STPBT1: INX H MOV A,M ; next char CPI ',' JZ STPBT1 ; skip over the ',' ANA A JZ BDEXIT ; no input CPI 'A' ; first value JC BDEXIT ; not valid CPI 'C'+1 ; last value JNC BDEXIT ; not valid SHLD TEMP0 ; save command line pointer CPI 'A' JZ STPBT2 ; one stop bit CPI 'B' JZ STPBT3 ; 1.5 stop bit ; MVI A,0CH ; two stop bits JMP STPBT4 ; STPBT2: MVI A,04H ; one stop bit JMP STPBT4 ; STPBT3: MVI A,08H ; 1.5 stop bit ; STPBT4: PUSH A ; save 'a' MVI B,1 ; offset to wr4 command MVI A,0CH ; clear stop bits CALL CLRWR ; POP A ORA M MOV M,A ; save new value in wr4 ; ; parity odd,even,none ; PARITY: LHLD TEMP0 ; get command line pointer back PAR1: INX H ; MOV A,M CPI ',' JZ PAR1 ; skip ',' SHLD TEMP0 ; save command line pointer ANA A JZ BDEXIT ; no entry CPI 'E' ; even JC BDEXIT ; not valid CPI 'O'+1 ; odd JNC BDEXIT ; must be between 'E' and 'O' CPI 'E' JZ PAR2 ; even parity CPI 'O' JZ PAR3 ; odd parity ; XRA A ; no parity JMP PAR4 ; PAR2: MVI A,03H ; even parity JMP PAR4 ; PAR3: MVI A,01 ; odd parity ; PAR4: PUSH A ; save 'a' MVI A,3 ; bits to clear for parity MVI B,1 ; offset to wr4 command reg LXI H,DART CALL CLRWR ; clear bits POP A ORA M MOV M,A ; save parity ; HANDSK: LHLD TEMP0 ; get command line pointer HAND1: INX H MOV A,M ; CPI ',' ; skip delimiter JZ HAND1 ANA A JZ BDEXIT ; end of command line CPI 'Y' ; yes JZ HAND2 CPI 'N' ; no JNZ BDEXIT ; HAND2: PUSH PSW ; save Y or N LDA PORT ; port A or B ANA A JZ HAND3 ; do port A POP PSW ; ANI 01H ; lsb of Y=1,N=0 STA HSB JMP GOODEX ; ; HAND3: POP PSW ; restore 'a' ANI 01H ; mask lsb STA HSA JMP GOODEX ; make changes ; ; getspd, sets port speed value, entered with 'de'= to command ; input. set ctc divisor wr4 in syspram ; GETSPD: XCHG ; string to 'de' CALL COMPARE DB '110',0 MVI A,0 ; 0=110 baud JNC SPDEXT CALL COMPARE DB '300',0 MVI A,1 ; 1=300 baud JNC SPDEXT CALL COMPARE DB '450',0 MVI A,2 ; 2=450 baud JNC SPDEXT CALL COMPARE DB '600',0 MVI A,3 ; 3=600 baud JNC SPDEXT CALL COMPARE DB '1200',0 MVI A,4 ; 4=1200 baud JNC SPDEXT CALL COMPARE DB '2400',0 MVI A,5 ; 5=2400 baud JNC SPDEXT CALL COMPARE DB '4800',0 MVI A,6 ; 6=4800 baud JNC SPDEXT CALL COMPARE DB '9600',0 MVI A,7 ; 7=9600 baud JNC SPDEXT CALL COMPARE DB '19200',0 MVI A,8 ; 8=19200 baud JNC SPDEXT CALL COMPARE DB '38400',0 MVI A,9 ; 9=38400 baud JNC SPDEXT CALL COMPARE DB '19.2',0 MVI A,8 ; 8=19200 baud JNC SPDEXT CALL COMPARE DB '38.4',0 MVI A,9 ; 9=38400 baud JC BDEXIT ; SPDEXT: STA SPEED MVI A,0C0H ; clear clock divisor mask MVI B,1 ; offset to wr4 command CALL CLRWR PUSH H ; save wr4 address LDA SPEED LXI H,CLK ; clock table CALL LOOKUP ; get clock divisor address MOV A,M ; clock divisor POP H ; get wr4 address ORA M ; or in clock divisor bits MOV M,A ; and save LDA SPEED LXI H,CTCDIV ; ctc divisor table CALL LOOKUP ; returns 'l'=ctc command, 'h'=ctc divisor LDA PORT ; see if port a or b ANA A JZ SPEX1 ; zero=port a LDA SPEED ; get speed setting CPI 8 ; more than 9600 ? JNC BDEXIT ; yes, exit SHLD CTC1 ; for port b RET ; SPEX1: SHLD CTC0 ; for dart a LDA SPEED CPI 8 ; less than 19.2 JC SPDEX2 ; yes MVI A,80H ; turn off dtr MVI B,3 ; offset to wr5 CALL CLRWR RET ; SPDEX2: MVI A,80H ; clear dtr MVI B,3 ; offset to wr5 CALL CLRWR MVI A,80H ; set dtr ORA M MOV M,A ; store dtr on RET ; PRN: CALL DELIM ; get subcommand pointer JC BDEXIT ; delimeter not found, exit XCHG ; subcommand pointer in 'de' CALL COMPARE DB 'PORT A',0 MVI B,40H JNC PRN1 CALL COMPARE DB 'PORT B',0 MVI B,00H JNC PRN1 CALL COMPARE DB 'PARALLEL',0 MVI B,80H JC BDEXIT ; no match, exit ; PRN1: LDA IOBYT ANI 3FH ; mask lst: bits ORA B STA IOBYT JMP GOODEX ; ; exit back to system ; GOODEX: CALL PUTBIO ; put changes in bios LXI H,GDEXIT PUSH H ; set up for return MVI A,57 ; ioinit offset LHLD BIOS ; get warm boot address MOV L,A ; modify with offset to init PCHL ; do bios init ; GDEXIT: CALL ILPRT DB cr,lf,lf DB ' New parameters installed in bios and initialized' DB cr,lf,0 ; ; exit, no warm boot ; EXIT: LHLD RETURN ; recover ccp stack pointer SPHL ; RET ; ; exit, error in command line ; BDEXIT: CALL ILPRT DB cr,lf,'Command line error',cr,lf,lf,0 JMP START2 ; ; getnxt, return the single character options seperated by commas ; on the command line. 'hl' points to option ; GETNXT: LHLD TEMP0 ; get command line pointer GETNX1: MOV A,M CPI ',' INX H ; point to value or next position JNZ GETNX1 MOV A,M ; get option SHLD TEMP0 ; save pointer ANA A RNZ STC ; set carry=end of command line RET ; ; ; clrwr, clear bits in dart wr. entered with mask in 'a' and offset ; in 'b'. returns address of reg in 'hl' ; CLRWR: PUSH PSW ; save 'a' LXI H,DART ; dart sysint values LDA PORT ; port has offset MVI D,0 MOV E,A DAD D ; dart 'a' or 'b' side MOV E,B ; offset to reg DAD D ; 'hl'=reg location POP A ; restore mask CMA ; invert bits ANA M ; clear bits MOV M,A ; save wr with bits cleared RET ; ; lookup, entered with address table in 'hl' and multiplier in 'a', ; returns with 'hl' pointing to variable length data string. ; LOOKUP: MVI D,0 ; zero 'd' ADD A ; 'a'x2 MOV E,A DAD D ; add 'de' to 'hl' MOV E,M ; get address table in 'de' INX H ; next byte MOV D,M XCHG ; address of string in 'hl' RET ; ; delim, returns address of first character after delimiter (=) ; or carry set if none found ; DELIM: LXI H,CMDTAL ; command tail DELIM1: INX H MOV A,M ANA A ; see if zero JZ DELIM2 ; end of command line CPI '=' JNZ DELIM1 ; loop till delimiter or end INX H ; start of subcommand SHLD TEMP0 ; save start of subcomand RET ; DELIM2: STC ; set carry=no subcommad RET ; ; now, print current parameters ; NOW: CALL ILPRT DB cr,lf,'Current System Configuration is:',lf DB cr,lf,'Terminal = ',0 LDA IOBYT ANI 03H ; mast CON: bits LXI H,DEV ; device table CALL LOOKUP CALL PRINT ; print device CALL ILPRT DB cr,lf,'Printer = ',0 LDA IOBYT ANI 0C0H ; mask LST: bits RLC RLC ; put bits in low nibble LXI H,DEV ; device table CALL LOOKUP CALL PRINT ; CALL ILPRT DB cr,lf,lf DB 'Serial Port A: ' DB 'Baud Rate = ',0 LXI B,CTC0 LXI D,AWR4C ; A dart wr4 CALL GTBAUD ; get baud rate CALL PRINT ; print baud rate CALL ILPRT DB cr,lf DB ' Data bits = ',0 LDA AWR3C ; wr3 has number of data bits CALL SHDBIT ; show data bits CALL ILPRT DB cr,lf DB ' Stop bits = ',0 LDA AWR4C ; wr4 has stop bits CALL SHSBIT ; show stop bits CALL ILPRT DB cr,lf DB ' Parity = ',0 LDA AWR4C ; wr4 has parity CALL SHPBIT ; show parity CALL ILPRT DB cr,lf DB ' Handshake = ',0 LDA HSA CALL SHHSK ; show handshake ; CALL ILPRT DB cr,lf,lf DB 'Serial Port B: ' DB 'Baud Rate = ',0 LXI B,CTC1 LXI D,BWR4C ; A dart wr4 CALL GTBAUD ; get baud rate CALL PRINT ; print baud rate CALL ILPRT DB cr,lf DB ' Data bits = ',0 LDA BWR3C ; wr3 has number of data bits CALL SHDBIT ; show data bits CALL ILPRT DB cr,lf DB ' Stop bits = ',0 LDA BWR4C ; wr4 has stop bits CALL SHSBIT ; show stop bits CALL ILPRT DB cr,lf DB ' Parity = ',0 LDA BWR4C ; wr4 has parity CALL SHPBIT CALL ILPRT DB cr,lf DB ' Handshake = ',0 LDA HSB CALL SHHSK ; show handshake CALL ILPRT DB CR,LF,0 JMP EXIT ; ; show handshake ; SHHSK: LXI H,HNDSH ; yes or no CALL LOOKUP JMP PRINT ; print, return ; ; show parity ; SHPBIT: ANI 03H ; mask parity bits LXI H,PRTY ; parity table CALL LOOKUP JMP PRINT ; print parity, and return ; ; show stop bits ; SHSBIT: ANI 0CH ; mask stop bits RRC RRC ; put bits in position LXI H,SBITS ; stop bits table CALL LOOKUP JMP PRINT ; print it, return to caller ; ; show data bits ; SHDBIT: ANI 0C0H ; mask data bit length RLC RLC ; put bits in low nibble LXI H,DBITS ; data bits table CALL LOOKUP JMP PRINT ; print it, return to caller ; ; print the baud rate. 'bc' points to ctc init string, ; 'de' points to dart init string ; GTBAUD: LDAX B ; get first ctc byte CPI 3 ; reset? JZ GTBAU1 ; must be 19.2 + CPI 47H LXI H,B1 RNZ ; must be 7, print 110 baud INX B ; point to second byte of ctc string LDAX B CPI 13 LXI H,B96 RZ ; print 9600 baud CPI 26 LXI H,B48 RZ ; print 4800 baud CPI 52 LXI H,B24 RZ ; print 2400 baud CPI 104 LXI H,B12 RZ ; print 1200 baud CPI 208 LXI H,B4 RNZ ; print 450 baud LDAX D ; wr4 info ANI 0C0H ; mask CPI 40H LXI H,B6 RZ ; 600 baud LXI H,B3 ; 300 baud RET ; GTBAU1: LDAX D ; wr4 info ANI 0C0H CPI 40H LXI H,B384 RZ LXI H,B192 RET ; ; compare a string of characters addressed by 'de' terminated ; with 0h. returns with cary set if no match ; COMPARE: XTHL ; the stack has the pointer to the PUSH D ; save string address CMPA: MOV A,M ; ANA A ; the end ? JZ SAME ; made it to end all equal LDAX D ; CMP M ; JNZ NSAME ; not same INX H ; INX D ; JMP CMPA ; ; NSAME: XRA A ; keep going till end '0' so we INX H ; return to correct place CMP M ; JNZ NSAME+1 ; STC ; set carry ; SAME: POP D ; restore string address INX H ; point to next inst after compare string XTHL ; replace value on stack with 'hl' for ret. RET ; ; ilprt, display a string of characters terminated by a 0h ; ILPRT: XTHL ; stack has address of string ILPRT1: MOV A,M ANA A ; zero ? JZ ILPRT2 CALL FCN2 INX H JMP ILPRT1 ; ILPRT2: XTHL ; put new return address on stack RET ; ; clear the screen ; CLRSCN: MVI A,CR ; print carriage return CALL FCN2 MVI B,18 ; load 'b' count CLRSC1: MVI A,LF ; do line feeds CALL FCN2 DCR B JNZ CLRSC1 RET ; ; print a string terminated by 0h. entered with 'hl' pointing to string ; PRINT: MOV A,M ; get byte ANA A RZ ; the end CALL FCN2 ; console write INX H JMP PRINT ; ; wait, wait 10 msec after 'lf' for slow terminals ; WAIT: MVI B,4 ; LXI D,0 ; WAIT1: INX D ; 1.50 MOV A,E ; 1.00 CMP D ; 1.00 JNZ WAIT1 ; 2.50 = 6.00 DCR B RZ JMP WAIT1 ; ; getbio, finds current system parameters in bios and moves them into ; program area. ; GETBIO: LHLD BIOS ; get warm boot bios address MVI L,40H ; parameters start here MVI B,64 ; number of bytes to move LXI D,SYSPRAM ; store here JMP LDIR ; move it ; ; putbio, takes updated parameters and places them in bios ; PUTBIO: LHLD BIOS ; get warm boot bios address MVI L,40H ; parameters start here XCHG ; destination in 'de' MVI B,64 ; number of bytes to move LXI H,SYSPRAM ; new param here ; fall thru and move it ; ; ldir, simulates the z80 ldir instruction ; LDIR: MOV A,M ; get byte from source STAX D ; store destination INX H ; next source INX D ; next destination DCR B ; count down JNZ LDIR ; no RET ; yes zero, return ; ; --------------------------------------------------------- ; *** system calls *** ; --------------------------------------------------------- ; bdos function 1, console read ; FCN1: PUSH H ; save registers PUSH D PUSH B MVI C,1 ; console read CALL BDOS POP B POP D POP H RET ; ; bdos function 2, console write ; FCN2: PUSH H ; save registers PUSH D PUSH B PUSH PSW MOV E,A MVI C,2 ; console write CALL BDOS POP PSW CPI LF CZ WAIT ; wait after 'lf' for slow POP B ; terminals POP D POP H RET ; ;---------------------------------------------------------- ; lookup tables ;---------------------------------------------------------- ; ; clock divisor ; CLK: DW CK16 ; 110 baud DW CK32 ; 300 baud DW CK16 ; 450 baud DW CK16 ; 600 baud DW CK16 ; 1200 baud DW CK16 ; 2400 baud DW CK16 ; 4800 baud DW CK16 ; 9600 baud DW CK32 ; 19200 baud DW CK16 ; 38400 baud ; ; ctc commamds ; CTCDIV: DB 07H,142 ; timer mode, 110 baud DB 47H,208 ; counter mode, 300 baud DB 47H,139 ; counter mode, 450 baud DB 47H,208 ; counter mode, 600 baud DB 47H,104 ; counter mode, 1200 baud DB 47H,52 ; counter mode, 2400 baud DB 47H,26 ; counter mode, 4800 baud DB 47H,13 ; counter mode, 9600 baud DB 3,0 ; clear ctc above 9600, 19.2 baud DB 3,0 ; ditto for 38.4 baud ; ; table for device ports ; DEV: DW SPB ; serial port b, i/o bit 00 DW SPA ; serial port a, i/o bit 01 DW PPO ; parallel port, i/o bit 10 ; ; handshake ; HNDSH: DW N DW Y ; ; data bits per character ; DBITS: DW BITS5 DW BITS7 DW BITS6 DW BITS8 ; ; number of stop bits ; SBITS: DW PRTS DW SBIT1 DW SBIT15 DW SBIT2 ; ; parity table ; PRTY: DW PRTN DW PRTO DW PRTN DW PRTE ; ;---------------------------------------------------------- ; data strings ;---------------------------------------------------------- ; SPA: DB 'Serial Port A',0 SPB: DB 'Serial Port B',0 PPO: DB 'Parallel Port',0 ; BITS5: DB '5 bits per character',0 BITS6: DB '6 bits per character',0 BITS7: DB '7 bits per character',0 BITS8: DB '8 bits per character',0 ; SBIT1: DB '1 stop bit',0 SBIT15: DB '1.5 stop bits',0 SBIT2: DB '2 stop bits',0 ; PRTN: DB 'none',0 PRTO: DB 'odd',0 PRTE: DB 'even',0 PRTS: DB '?? illegal bit combination',0 ; B384: DB '38400',0 B192: DB '19200',0 B96: DB '9600',0 B48: DB '4800',0 B24: DB '2400',0 B12: DB '1200',0 B6: DB '600',0 B4: DB '450',0 B3: DB '300',0 B1: DB '110',0 ; Y: DB 'yes',0 N: DB 'no',0 ; SRA: DB 0 SRB: DB 1 SRC: DB 2 SRD: DB 3 ; CK16 DB 40H CK32 DB 80H CK64 DB 0C0H ; ; --------------------------------------------------------- ; parameter storage area ; PORT: DS 1 ; port a=0,port b=1 SPEED: DS 1 ; save speed value TEMP0: DW 1 ; storage for start of subcommand RETURN: DW 1 ; storage for ccp stack pointer ; ; system parameters from bios as located at bios+40h ; SYSPRAM: CTC0: DW 1 ; ctc0 init values CTC1: DW 1 ; ctc1 init values CTC2: DW 1 ; ctc2 init values CTC3: DW 1 ; ctc3 init values ; DART: ; dart init values AWR4: DS 1 ; wr 4, dart 'A' side AWR4C: DS 1 ; wr 4 command AWR5: DS 1 ; wr 5 AWR5C: DS 1 ; wr 5 command AWR3: DS 1 ; wr 3 AWR3C: DS 1 ; wr 3 command DS 4 ; BWR4: DS 1 ; wr 4, dart 'B' side BWR4C: DS 1 ; wr 4 command BWR5: DS 1 ; wr 5 BWR5C: DS 1 ; wr 5 command BWR3: DS 1 ; wr 3 BWR3C: DS 1 ; wr 3 command DS 4 ; NDISK: DS 1 ; number of disk drives ; STPRAT: DS 4 ; disk drive step rate ; IOBYT: DS 1 ; i/o byte ; ATOCMD: DS 10 ; auto-command ; HSA: DS 1 ; hand shake port a HSB: DS 1 ; hand shake port b ; VER: DS 1 ; bios version number ; ORG SYSPRAM+40H DS 32 ; stack area STACK: END START