;************************************************** ; ; BASICODE READ ; ; DIT OPENBAAR PROGRAMMA MAG GECOPIEERD EN GEDISTRIBEERD ; WORDEN, MITS INHOUDENDE DE VOLGENDE COPYRIGHT NOTICE ; ; " DIT PROGRAMMA ; BETREFFENDE EEN IMPLEMENTATIE VAN DE ; NOS BASICODE ; ; IS TER BESCHIKKING GESTELD DOOR DE ; HOBBY COMPUTER CLUB (HOLLAND) " ; ; ; NOS P.O. 1200 1200BE HILVERSUM (HOBBYSCOOP) ; HCC P.O. 149 2250AC VOORSCHOTEN (CP/M gg) ; ; Implementatie: ; Albert van der Horst ; t.b.v. FORTH gebruikersgroep (HCC) ; ;************************************************* ORG 100H CALL PRINT DB CTRLZ,LF,LF,' ** CP/M BASICODE LEES ' DB '** RELEASE 1.0',CR,LF,LF,0 ; ; ;************************************************* ; ; Algemene opmerking: ; Daar ook CP/M de registers van de Z80 niet ; intact laat bij aanroepen naar het systeem, ; is hier de regel aanhouden dat registers altijd ; verpest worden door subroutines, tenzij anders ; vermeld. ; ;------------- VERANDERLIJKE EQUATES --------------- ; ; In het algemeen zal men voor ieder type computer ; een verantwoorde keus moeten maken uit de volgende ; opties, alsmede hardware adressen in moeten vullen. ; ; ASSEMBLER SWITCH ALS HIJ 1 IS, BETEKENT HET DAT MEMMAP EQU 1 ; De Centronics poort is 'memory mapped' DEBUG EQU 0 ; Debug instrukties meegeassembleerd ; Een langzame processor kan hier niet tegen! FIG EQU 0 ; Een FIGFORTH blokken file wordt ingelezen, ; d.w.z. alle CR en LF's weg, alle regels ; worden aangevuld tot 64 characters. OSBRN EQU 1 ; Speciaal voor OSBORNE: bank switching ; HARDWARE EQUATES CRIT EQU 55 ; Grens tussen lengte O of 1 bit PAPORT EQU 2902H ; Parallel port (memory mapped) ; Hier moet het Centronics 'PRINTER READY' ; signaal op binnen komen. SCREEN EQU 0F000H ; Memory mapped video screen ; ;------------- VASTE EQUATES -------------------------------- BDOS EQU 5H DMA EQU 80H STX EQU 02H ETX EQU 03H LF EQU 0AH CR EQU 0DH CTRLZ EQU 1AH ; CONTROL-Z FCB EQU 5CH ; Standaard file control block ;------------------------------------------------- JMP STACK ; ; ================================================ ; IF NOT OSBRN ; Normale situatie DS 20H ; Reserveer stack ruimte ENDIF IF OSBRN ; Programma moet boven 4000H draaien ORG 4020H ; wegens of Osborne bankswitching ENDIF STACK: LXI H,STACK SPHL ; - - - - - WACHT OP KEYBOARD - - - - - - - - - - - CALL PRINT DB 'START CASSETTE EN GEEF RETURN',CR,LF,0 MVI C,1 CALL BDOS ;----------- LEZEN VAN CASSETTE -------------------- ; - - - - - DISABLE INTERRUPTS - - - - - - - - - - ; ; DIT IS MISSCHIEN NIET VOOR ELK SYSTEEM VAN BELANG DI ; - - - - - INITIALISEREN - - - - - - - - - - - - - IF OSBRN CALL BANK2 ENDIF LXI H,BUFFER-1 SHLD LASTCH ; ;------- HAAL DE BYTES EEN VOOR EEN BINNEN ---------------- ; ; Op elk punt waar gelezen wordt kan de gebruiker ; laten afbreken. Men komt dan in de error afhandeling ; aan het eind van dit gedeelte (LABEL ERROR2) REP1: CALL SYNCH ; Zoek volgende startbit CALL BYTOBF ; Haal byte van cassette ; en plaats in buffer CALL CALCHK ; Checksum bijwerken MOV A,C ; Naar video ter controle STA SCREEN CPI ETX+80H ; ETX ->voorlaatste char JNZ REP1 ; Anders volgende byte ; - - - - CHECKSUM - - - - - - - - - - - - - - - CALL SYNCH CALL BYTOBF ; Haal checksum van cassette LDA CHKSUM ; Haal berekende checksum CMP C ; Moet gelijk zijn JNZ ELSE1 MVI A,0FFH JMP END2 ELSE1: MVI A,0 END2: STA OKAY JMP END1 ; - - - - - ON ERROR GEDEELTE - - - - - - - - - - - ERROR2: MVI A,0 ; Natuurlijk niet okay STA OKAY ; want het inlezen werd onderbroken ; door de gebruiker LHLD LASTCH ; Verzekerd van ETX INX H MVI M,ETX SHLD LASTCH ; - - - - - AFSLUITEN - - - - - - - - - - - - - - END1: NOP IF OSBRN CALL BANK1 ; Bank terugschakelen ENDIF EI CALL MESSGE ; Hoe afgelopen? ; ;------- VERPLAATS VAN BUFFER NAAR SCHIJF -------------- ; ; In dit hele gedeelte wijst HL naar het te ; verwerken byte in de buffer. ; ;- - - - - - INITIALISEREN - - - - - - - - ; CALL OPEN LHLD FRSTCH ; Skip rommel voor STX INX H ; Skip ook nog over STX ; - - - - - LOOP OVER DMA BUFFERS - - - - - - - - REP6: LXI D,DMA MVI B,80H ; Bytes per record REP7: CALL COPCHR ; Byte naar DMA buffer JZ OUT3 ; Z: d.w.z. ETX gevonden DCR B JNZ REP7 PUSH H CALL WRITE ; BUFFER VOL : SCHRIJVEN POP H JMP REP6 ; - - - - - LAATSTE RECORD - - - - - - - - - - - ; ; Vul de laatste buffer met CTRLZ's op OUT3: DCX D ; Overschrijf ETX REP2: MVI A,CTRLZ STAX D INX D DCR B JNZ REP2 CALL WRITE ;- - - - - - EINDE - - - - - - - - - - - - - - CALL CLOSE JMP 0 ; Terug naar CP/M ;************************************************** ; ; SUBROUTINE GEBIED ; ;************************************************** ; --------- BYTE NAAR DMA BUFFER ------------- ; ; Verplaats een byte van input buffer naar DMA buffer. ; Als Z, dan zijn we ETX tegengekomen. ; Stelt HL ( 'van'-pointer) en DE ('naar'-pointer bij) ; Behoudt het BC register (teller), tenzij bij FIG ; opvulakties. COPCHR MOV A,M ; Copieer buffer naar DMA INX H ANI 7FH ; 7e BIT ERAF STAX D INX D ; CPI ' ' ; Controle char? ; JNC NORMAL CPI LF JZ NORMAL CPI CR ; Enige toegestane controle character IF FIG ; Bij FIGFORTH speciale opvul actie CZ OPVUL ENDIF IF NOT FIG JZ CRLF JMP NORMAL CRLF: DCX H ; Frommel er een LF bij MVI M,LF ; Wordt straks pas opgepikt! ENDIF NORMAL: CPI ETX ; Z vlag betekent einde RET ;---------- OPVULLEN MET SPATIES ----------------- ; ; Alleen voor FIG FORTH files ; Stelt HL,DE en BC bij (zie COPCHR) IF FIG OPVUL MVI A,020H ; Spatie DCX D STAX D ; Overschrijf CR, INX D ; die er al was. REP9 MVI A,20H ; Schrijf spaties STAX D INX D DCR B MOV B,A CPI 41H ; Tot 1e regel vol RZ CPI 01H ; Of 2e regel vol RZ JMP REP9 ENDIF ;---------- SYNCHRONISEREN --------------------- ; ; Wacht op 0-bit SYNCH: LXI H,PAPORT CALL BITPS MVI A,CRIT/2 ; HET GAAT HIER OM HALVE PERIODE CMP E JNC SYNCH CALL BITPS ; OOK TWEEDE KEER LANG? MVI A,CRIT/2 CMP E IF DEBUG MOV A,E STA SCREEN+3 ENDIF JNC SYNCH RET ; --------- VERWIJDER CHARACTERS -------------------- ; ; Verwijder alle char's, gelijk aan register C REMOVE LXI D,FRSTCH LXI H,FRSTCH REP8: LDAX D ; COPIEER VAN D MOV M,A ; NAAR H CMP C JZ END4 ; INDIEN HET EEN FOUT CHAR IS INX H ; INCREMENTEER DAN H NIET END4: INX D CPI ETX JNZ REP8 DCX H SHLD LASTCH ; NIEUW EINDPUNT RET ; ------- HAAL BYTE OP ----------------------------- ; ; Haalt een byte op en plaats het in de buffer. ; Uitvoer: C bevat het gelezen byte. ; BYTOBF: MVI C,80H ; Als dit bit weer tevoorschijn ; komt zijn we klaar DO1: CALL BITIN ; lees bit MOV A,C ; Schuif bit in C erbij RAR MOV C,A JNC DO1 LHLD LASTCH ; Plaats c in buffer INX H MOV M,C SHLD LASTCH RET ; --------- HOUDT CHECKSUM BIJ ------------------- ; ; Invoer: C ; CALCHK: MOV A,C ; In C zit het zojuist gelezen byte CPI STX+80H LDA CHKSUM JNZ END3 ; Als STX gelezen was XRA A ; initialisieer dan checksum opnieuw SHLD FRSTCH ; en onthoud dit adres END3: XRA C STA CHKSUM RET ; ------------- SWITCH NAAR BANK 1 ------------- ; ; Zie OSBORNE USER GUIDE 262 ( REV.12/15/82) IF OSBRN BANK1: OUT 1 MVI A,1 STA 0EF08H RET ; ------------- SWITCH NAAR BANK 2 ------------------ ; ; Zie OSBORNE USER GUIDE 262 ( REV.12/15/82) BANK2: OUT 0 MVI A,0 STA 0EF08H RET ENDIF ; ------------- HAAL EEN BIT BINNEN ------------- ; ; Bepaal de lengte van de positieve en negatieve ; fase. ; 1/1200 sec = 833.25 usec ; Op de Osborne (4 Mhz) is dat 3333 cycles ; Bij overschrijding hiervan een sprong naar ; de foutafhandeling. ; BC blijft behouden door deze routine heen, C bevat ; immers het te lezen byte in opbouw BITIN: PUSH B MVI B,2 ; 2 fasen voor '1-bit' REP4: CALL BITPS ; Wacht 1e periode MOV D,E ; Bewaar lengte eerste helft CALL BITPS ; Wacht 2e periode MOV A,E ADD D ; Totale lengte IF DEBUG STA SCREEN+3 ENDIF CPI CRIT ; 0 of 1 bit? JNC OUT2 ; Uit de loop bij 1200 periode DCR B JNZ REP4 ; Anders: skip 2e golf OUT2: POP B RET ; ----------- MEET LENGTE PERIODE ----------------- ; ; HL wijst al naar de poort (bij memory mapped) ; Bij time-out wordt gekeken of er een toets ingedrukt is. ; Zo ja, dan breekt het inlezen af. IF MEMMAP BITPS: MOV A,M ; Lees poort MVI E,0 ; Init teller REP5: INR E ; Meet lengte JZ OUT1 ; Timeout CMP M ; Veranderd? JZ REP5 ; Zo niet herhaal RET ENDIF ; - - - - HET VOLGENDE NIET GETEST - - - - - - - IF NOT MEMMAP BITPS: IN PAPORT ; Lees poort MOV L,A ; Bewaar in L MVI E,0 ; Init teller REP5: INR E ; Meet lengte JZ OUT1 ; Timeout IN PAPORT CMP L ; Veranderd? JZ REP5 ; Zo niet herhaal RET ENDIF ; - - - - - TIME OUT - - - - - - - - - - OUT1: IF OSBRN CALL BANK1 ENDIF CALL KBD ; Wil men afbreken? PUSH PSW IF OSBRN CALL BANK2 ENDIF POP PSW JNZ REP5 ; Zoniet toch doorgaan JMP ERROR2 ; ---------- PRINT DE TEKST VOLGENDE OP DE CALL --------------- PRINT POP H ; Haal return address op MOV A,M ; Haal een letter op INX H ORA A JZ END5 PUSH H CALL CRT JMP PRINT END5 PCHL ; RETURN ; ----------- HOE AFGELOPEN ----------------------- MESSGE: CALL PRINT DB CR,LF,' DE CHECKSUM KLOPT ',0 LDA OKAY ANA A RNZ CALL PRINT DB 'NIET',0 RET ;================================================= ; ; INTERFACE MET CP/M ; ------------------ ; ;================================================= ; --------------- FUNKTIE SCAN FOR CHAR ----------- ; ; Uitvoer : Z-vlag betekent toets ingedrukt KBD PUSH H PUSH D PUSH B EI MVI C,0BH CALL BDOS ANI 1 ; TEST L.S. BIT CPI 1 DI POP B POP D POP H RET ; ---------- FUNKTIE PRINT A CHAR ------------ CRT MOV E,A ; OUTPUTS 'A' IN ASCII MVI C,2 CALL BDOS RET ; -------- FUNKTIE MAAK FILE ------------------- ; ; OPENT DE FILE MET NAAM OP FCB VOOR SCHRIJVEN ; OPEN: MVI C,22 LXI D,FCB CALL BDOS RET ; ------ FUNKTIE SCHRIJF RECORD --------------- ; ; SCHRIJF HET volgende RECORD ; WRITE: MVI C,21 LXI D,FCB CALL BDOS RET ; -------- FUNKTIE SLUIT FILE -------------- ; ; SLUIT HET SCHRIJVEN AF ; CLOSE: MVI C,16 LXI D,FCB CALL BDOS RET ;================================================= ; ; START VAN BUFFER GEBIED ; ----------------------- ; ;================================================= ; OKAY DB 0 ; BOOLEAN: BETEKENT ; - ER WAS STX ; - ER WAS ETX ; - DE CHECKSUM KLOPTE FRSTCH DW 0 ; ADRES VAN EERSTE CHAR : STX ; ALS OKAY DUS STX LASTCH DW 0 ; ADRES VAN LAATSTE CHAR : ETX ; ALS OKAY DUS ETX CHKSUM DB 0 ; LOPENDE CHECKSUM BUFFER: DS 5000H