title Basicode Treiber fuer JOYCE name ('BASCOD') .comment | In diesem Treiber sind alle Programm Module aufgefuert, die zur Bildschirm- und Zeichenbearbeitung benoetigt werden. Ebenfalls ein Modul zur Erzeugung von Toenen. Disassembliert von Werner Cirsovius Hinweis: Die Routine "OREADCHAR" verwendet einen Aufruf zum Lesen der Matrix eines Zeichens aus dem Videospeicher. Der Aufruf erfolgt ueber die Adresse "1764h" im Video-Memory, nachzulesen z.B. in der CPC-Artikelserie "Im Herzen des JOYCE". Allerdings kann diese Adresse variieren bei unterschiedlichen BIOS Versionen Daher kann an der Stelle alternativ ein eigener Code installiert werden | FALSE equ 0 TRUE equ NOT FALSE SYSGET equ FALSE ; Originale Routine waehlen ;SYSGET equ TRUE ; Eigene Routine waehlen SCR_GET macro rst 8 dw 1764h endm ROLLER equ 0b600h ; Adresse des Roller RAMs CHRMTX equ 0b800h ; Adresse der Zeichenmatrix BiZ equ 8 ; Bytes in einem Zeichen USERF equ 0fc5ah ; XBIOS-Adresse TEASK equ 00bfh ; Cursorposition abfragen SCRRUN equ 00e9h ; Ausfuehren im COMMON Memory ROWS equ 32 ; Anzahl vertikaler Zeichenzeilen COLS equ 90 ; Anzahl horizontaler Zeichenzeilen ; VLINE equ ROWS*BiZ ; Anzahl vertikaler Zeilen HLINE equ COLS*BiZ ; Anzahl horizontaler Zeilen .phase 0f000h ; ; Die Module werden ueber (MALLARD) BASIC aufgerufen, z.B. mit: ; ; CALL ROUTINE(PARAMETER1, PARAMETER2,...) ; ; BASIC-Interface: ; Parameter 1: ^HL ; Parameter 2: ^DE ; Parameter 3: ^BC ; ================ ; ; OSETCHAR(OPV,OPH,OPC) ; lf000:: ld a,(hl) ; OPV ex de,hl ld e,(hl) ; OPH inc hl ld d,(hl) ld h,b ; ^OPC kopieren ld l,c ld c,(hl) ; OPC cp (LOW VLINE-BiZ)+1; Test innerhalb der vertikalen Position jr c,lf00e ; Ok sub LOW VLINE-BiZ ; Sonst begrenzen lf00e: ld (lf0b1),a ; Zeile eintragen ld a,d cp HIGH HLINE ; Test innerhalb der horizontalen Position jr c,lf024 jr z,lf01c ld d,0 jr lf024 ; Sonst begrenzen lf01c: ld a,e cp (LOW HLINE-BiZ)+1 jr c,lf024 sub LOW HLINE-BiZ ld e,a ; Sonst begrenzen lf024: ld b,e ld a,e and 11111000b ; Bits maskieren ld e,a ld (lf0b2),de ld a,c ld (lf0b4),a ld a,b and 00000111b ld (lf0b5),a ld b,a ld a,11111111b jr z,lf040 lf03c: srl a djnz lf03c lf040: ld l,a cpl ld h,a ld (lf0b6),hl ld l,c ; Zeichen holen ld h,0 add hl,hl ; Index in Zeichenmatrix add hl,hl add hl,hl ld a,h add a,HIGH CHRMTX ; Adresse der Matrix ld h,a ld (lf0b8),hl ld bc,lf05c call USERF dw SCRRUN ret ; ; ; lf05c: ld b,BiZ lf05e: push bc ld hl,lf0b1 ; Zeiger auf Zeile ld e,(hl) ld a,(hl) inc (hl) and 00000111b ld c,a ld d,0 ex de,hl add hl,hl ld a,h add a,HIGH ROLLER ld h,a ld e,(hl) ; Zeilenadresse aus Roller-RAM laden inc hl ld d,(hl) ex de,hl add hl,hl ld b,0 or a sbc hl,bc push hl pop ix ld hl,(lf0b8) ; Adresse der Matrix laden ld de,(lf0b2) add ix,de ld d,(hl) ld e,0 ld a,(lf0b5) ld b,a or a jr z,lf096 lf090: srl d rr e djnz lf090 lf096: ld a,(lf420) ld hl,(lf0b6) and h or d ld (lf420),a ld a,(lf421) and l or e call lf422 ld hl,lf0b8 inc (hl) pop bc djnz lf05e ret ; lf0b1: ds 1 ; Zeile fuer Zeichen lf0b2: ds 2 lf0b4: ds 1 lf0b5: ds 1 lf0b6: ds 2 lf0b8: ds 2 ; ; OSETPOINT(OPV,OPH,OPM) ; lf0ba:: ld a,(hl) ; OPV ex de,hl ld e,(hl) ; OPH inc hl ld d,(hl) ld h,b ; ^OPM kopieren ld l,c ld c,(hl) ; OPM ld b,a ld (lf15b),bc ; OPM (C) + OPV (B) speichern ld (lf15d),de ; OPH speichern ld bc,lf0d4 call USERF dw SCRRUN ret ; ; ; lf0d4: ld bc,(lf15b) ; OPM (C) + OPV (B) laden ld de,(lf15d) ; OPH laden lf0dc: ld a,b ld (lf15c),a ; OPV speichern ld a,d cp HIGH HLINE ; Test horizontale Position jr c,lf0f3 jr z,lf0eb ld d,0 ; Bei Ueberlauf begrenzen jr lf0f3 lf0eb: ld a,e cp LOW HLINE jr c,lf0f3 sub (LOW HLINE)-1 ld e,a lf0f3: ld b,e ld a,e and 11111000b ld e,a ld (lf15d),de ; OPH speichern ld a,c and 00000011b ld (lf15b),a ; OPM speichern ld a,b and 00000111b ld (lf15f),a ld b,a ld a,10000000b jr z,lf111 lf10d: srl a djnz lf10d lf111: ld l,a cpl ld h,a ld (lf160),hl ld hl,lf15c ; Zeiger auf OPV ld e,(hl) ld a,(hl) and 00000111b ld c,a ld d,0 ex de,hl add hl,hl ld a,h add a,HIGH ROLLER ld h,a ld e,(hl) ; Zeilenadresse aus Roller-RAM laden inc hl ld d,(hl) ex de,hl add hl,hl ld b,0 or a sbc hl,bc push hl pop ix ld de,(lf15d) ; OPH laden add ix,de ld a,(lf15b) ; OPM laden ld b,(ix+0) ld hl,(lf160) or a ; OPM testen jr nz,lf14c ; ; OPM=00000000 ; lf146: ld a,b and h ld (ix+0),a ret lf14c: rra jr nc,lf155 ; ; OPM=XXXXXXX1 ; lf14f: ld a,b or l ld (ix+0),a ret ; ; OPM=XXXXXXX0 ; lf155: ld a,b and l jr z,lf14f jr lf146 ; lf15b: ds 1 ; OPM Wert lf15c: ds 1 ; OPV Wert lf15d: ds 2 ; OPH Wert lf15f: ds 1 lf160: ds 2 ; ; ODRAW(OPV,OPH,OPM) ; lf162:: ld a,(hl) ; OPV ex de,hl ld e,(hl) ; OPH inc hl ld d,(hl) ld h,b ; ^OPM kopieren ld l,c ld c,(hl) ; OPM ld b,a ld a,(lf246) ; Aktuellen Wert OPV laden ld hl,(lf247) ; Aktuellen Wert OPH laden ld (lf246),a ; Aktuellen Wert OPV speichern ld (lf242),bc ld (lf244),de ld (lf247),hl ; Aktuellen Wert OPH speichern sub b ld b,1 jr nz,lf185 dec b lf185: jr nc,lf18b dec b dec b cpl inc a lf18b: ld c,a ld a,b ld (lf249),a xor a ld b,a sbc hl,de ld de,1 jr nz,lf19a dec de lf19a: jr nc,lf1a5 dec de dec de ld a,h cpl ld h,a ld a,l cpl ld l,a inc hl lf1a5: ld (lf24b),de push hl pop de push hl xor a sbc hl,bc ld a,h ld (lf24d),a rla pop hl jr nc,lf1bd push de push bc push bc pop hl pop de pop bc lf1bd: ld (lf24e),hl srl h rr l ld (lf250),hl ld (lf252),bc ld (lf254),de ld bc,lf1d8 call USERF dw SCRRUN ret ; ; ; lf1d8: ld bc,(lf242) ld de,(lf244) call lf0dc ld a,(lf24d) rla jr c,lf1f6 ld hl,(lf244) ld bc,(lf24b) add hl,bc ld (lf244),hl jr lf201 lf1f6: ld bc,(lf242) ld a,(lf249) add a,b ld (lf243),a lf201: ld hl,(lf250) ld bc,(lf252) xor a sbc hl,bc ld (lf250),hl jr nc,lf236 ld bc,(lf254) add hl,bc ld (lf250),hl ld a,(lf24d) rla jr nc,lf22b ld hl,(lf244) ld bc,(lf24b) add hl,bc ld (lf244),hl jr lf236 lf22b: ld bc,(lf242) ld a,(lf249) add a,b ld (lf243),a lf236: ld hl,(lf24e) dec hl ld (lf24e),hl bit 7,h jr z,lf1d8 ret ; lf242: ds 1 lf243: ds 1 lf244: ds 2 lf246: ds 1 ; Aktueller Wert OPV lf247: ds 2 ; Aktueller Wert OPH lf249: ds 2 lf24b: ds 2 lf24d: ds 1 lf24e: ds 2 lf250: ds 2 lf252: ds 2 lf254: ds 2 ; ; OPOINT2(OPV,OPH) ; lf256:: ld a,(hl) ; OPV ld (lf246),a ; Speichern ex de,hl ld e,(hl) ; OPH inc hl ld d,(hl) ld (lf247),de ; Speichern ret ; ; OGETCUR ; lf263:: call USERF ; Position laden dw TEASK ld (lf26c),hl ret ; lf26c: ds 1 ; Horizontale Cursorposition (Spalte) lf26d: ds 1 ; Vertikale Cursorposition (Reihe) lf26e: ds 8 lf276: ds 1 ; Zeichen ; ; OREADCHAR ; lf277:: ld d,$-$ ; Vertikale Cursorposition (Reihe) ld e,$-$ ; Horizontale Cursorposition (Spalte) ld hl,lf26e call USERF dw lf284 ret ; ; Zeichenmatrix uebertragen ; lf284:: IF SYSGET jp MYGET ELSE SCR_GET ENDIF ; ; OFINDCHAR ; lf287:: ld bc,lf290 call USERF dw SCRRUN ret ; ; ; lf290: ld d,' ' ; Startzeichen ld ix,lf26e ; Auf gesuchtes Zeichen zeigen ld iy,CHRMTX+BiZ*' '; Auf erstes Zeichen in Matrix zeigen ; ; Normale Zeichen finden ; lf29a: ld a,(ix+0) ; Aus Matrix holen cp (iy+0) ; Vergleichen jr nz,lf2da ; Naechster Versuch ld a,(ix+1) cp (iy+1) jr nz,lf2da ld a,(ix+2) cp (iy+2) jr nz,lf2da ld a,(ix+3) cp (iy+3) jr nz,lf2da ld a,(ix+4) cp (iy+4) jr nz,lf2da ld a,(ix+5) cp (iy+5) jr nz,lf2da ld a,(ix+6) cp (iy+6) jr nz,lf2da ld a,(ix+7) cp (iy+7) jr z,lf34c ; Zeichen gefunden lf2da: inc d ld a,'~'+1 ; Test, ob letztes Zeichen cp d jr z,lf2e7 ; Ja, dann invers versuchen ld bc,BiZ add iy,bc ; Zeiger auf naechsten Matrixeintrag jr lf29a lf2e7: ld d,' ' ; Startzeichen ld iy,CHRMTX+BiZ*' '; Auf erstes Zeichen in Matrix zeigen ; ; Inverses Zeichen finden ; lf2ed: ld a,(ix+0) ; Aus Matrix holen xor 11111111b ; Invertieren cp (iy+0) ; Vergleichen jr nz,lf33d ; Naechster Versuch ld a,(ix+1) xor 11111111b cp (iy+1) jr nz,lf33d ld a,(ix+2) xor 11111111b cp (iy+2) jr nz,lf33d ld a,(ix+3) xor 11111111b cp (iy+3) jr nz,lf33d ld a,(ix+4) xor 11111111b cp (iy+4) jr nz,lf33d ld a,(ix+5) xor 11111111b cp (iy+5) jr nz,lf33d ld a,(ix+6) xor 11111111b cp (iy+6) jr nz,lf33d ld a,(ix+7) xor 11111111b cp (iy+7) jr z,lf34c ; Zeichen gefunden lf33d: inc d ld a,'~'+1 ; Test, ob letztes Zeichen cp d jr z,lf34a ; Ja, dann nicht gefunden ld bc,BiZ add iy,bc ; Zeiger auf naechsten Matrixeintrag jr lf2ed lf34a: ld d,0 ; Kein Zeichen gefunden lf34c: ld a,d ld (lf276),a ; Gefundenes Zeichen speichern ret ; lf351:: IF SYSGET ; ; Ermitteln der Adresse eines Zeichens ; EIN Register D haelt die vertikale Cursorposition (Reihe, 0..31) ; Register E haelt die horizontale Cursorposition (Spalte, 0..89) ; Register HL haelt Matrixpuffer ; AUS Matrixpuffer ist gefuellt mit dem Zeichen ; MYGET: push hl ; Puffer retten ld h,0 ld l,e ; HL=Spalte add hl,hl add hl,hl add hl,hl ; HL=Spalte*8 ld c,l ld b,h ; BC=Spalte*8 ld h,0 ld l,d ; HL=Zeile add hl,hl add hl,hl add hl,hl add hl,hl ; Zeile = Zeile * 16 ex de,hl ld iy,ROLLER ; Rolleradresse=$B600+Zeile add iy,de ; In IY ld l,(iy+0) ld h,(iy+1) ; Inhalt der Rolleradr. in HL add hl,hl ; ... * 2 add hl,bc ; Position des Zeichens pop de ; Puffer holen ld bc,BiZ ldir ; Matrix umkopieren ret ; ds 137 else ds 175 ENDIF CTRPORT equ 0f8h BEEPON equ 11 BEEPOFF equ 12 ; ; OADR - Erzeugung von Toenen ; lf400:: ld c,0 ld hl,$-$ ; Eintrag der Tondauern call lf409 ret ; lf409: di lf40a: ld a,BEEPON out (CTRPORT),a ld b,c lf40f: djnz lf40f ld a,BEEPOFF out (CTRPORT),a ld b,c lf416: djnz lf416 dec hl ld a,h or l jp nz,lf40a ei ret ; ; ; lf420: ds 1 lf421: ds 1 ; ; ; lf422: ld (lf421),a ld hl,(lf0b6) ld de,(lf420) ld a,(ix+16) bit 7,h jr z,lf441 bit 7,d jr z,lf43d set 7,a set 6,a jr lf441 lf43d: res 7,a res 6,a lf441: bit 6,h jr z,lf453 bit 6,d jr z,lf44f set 5,a set 4,a jr lf453 lf44f: res 5,a res 4,a lf453: bit 5,h jr z,lf465 bit 5,d jr z,lf461 set 3,a set 2,a jr lf465 lf461: res 3,a res 2,a lf465: bit 4,h jr z,lf477 bit 4,d jr z,lf473 set 1,a set 0,a jr lf477 lf473: res 1,a res 0,a lf477: ld (ix+16),a ld a,(ix+24) bit 3,h jr z,lf48f bit 3,d jr z,lf48b set 7,a set 6,a jr lf48f lf48b: res 7,a res 6,a lf48f: bit 2,h jr z,lf4a1 bit 2,d jr z,lf49d set 5,a set 4,a jr lf4a1 lf49d: res 5,a res 4,a lf4a1: bit 1,h jr z,lf4b3 bit 1,d jr z,lf4af set 3,a set 2,a jr lf4b3 lf4af: res 3,a res 2,a lf4b3: bit 0,h jr z,lf4c5 bit 0,d jr z,lf4c1 set 1,a set 0,a jr lf4c5 lf4c1: res 1,a res 0,a lf4c5: ld (ix+24),a ld a,(ix+0) bit 7,l jr z,lf4dd bit 7,e jr z,lf4d9 set 7,a set 6,a jr lf4dd lf4d9: res 7,a res 6,a lf4dd: bit 6,l jr z,lf4ef bit 6,e jr z,lf4eb set 5,a set 4,a jr lf4ef lf4eb: res 5,a res 4,a lf4ef: bit 5,l jr z,lf501 bit 5,e jr z,lf4fd set 3,a set 2,a jr lf501 lf4fd: res 3,a res 2,a lf501: bit 4,l jr z,lf513 bit 4,e jr z,lf50f set 1,a set 0,a jr lf513 lf50f: res 1,a res 0,a lf513: ld (ix+0),a ld a,(ix+8) bit 3,l jr z,lf52b bit 3,e jr z,lf527 set 7,a set 6,a jr lf52b lf527: res 7,a res 6,a lf52b: bit 2,l jr z,lf53d bit 2,e jr z,lf539 set 5,a set 4,a jr lf53d lf539: res 5,a res 4,a lf53d: bit 1,l jr z,lf54f bit 1,e jr z,lf54b set 3,a set 2,a jr lf54f lf54b: res 3,a res 2,a lf54f: bit 0,l jr z,lf561 bit 0,e jr z,lf55d set 1,a set 0,a jr lf561 lf55d: res 1,a res 0,a lf561: ld (ix+8),a ret ds 26 db 0 .dephase end