; File name liosz.m80 ; Written by Toshihumi Murata ; B U G sapporo japan ; 1st editing July 13, 1983 15:27:07 ; Last editing Sep. 20, 1983 16:44:12 ; Function Assembler part of LIOS ; Debugged(?) by Tomoshi Hirayama SONY ; Sept. 23, 1983 ; Debugged by Steve Schmitt -- save bc in CON_IN ; Oct. 26, 1983 ; Modified by Steve Schmitt -- GENERIC ; Jan. 11, 1984 *include SMC05.DEF SYSTEM EQU 5 SIMON EQU 8 CR EQU 0DH LF EQU 0AH BS EQU 08H GMOD EQU 0 ; Full screen mode SMOD EQU 1 ; Split screen mode TMOD EQU 2 ; Text screen mode PU EQU 0 PD EQU 1 BLINK EQU 40H ; blink bit mask TEXTPL EQU 084H ; 1st plane is used as text plane TRANSPL EQU 0C4H ; 2nd plane is used as trans. plane PALCOUNT EQU 16 ; The number of palettes NORMALMOD EQU 0 ; normal plot mode XORMOD EQU 1 ; xor plot mode WHITE EQU 7 ; White color code DSEG SCR_MOD: DB TMOD ; Holds current screen mode ALFAX: DB 0 ; x coordinate of alpha cursor ALFAY: DB 0 ; y coordinate of alpha cursor BLI: DB 0 ;blink flag ALFAC: DB 7 ;character color PALMAP: DS PALCOUNT*3 RETMAP: DS 2*3 SPLTTP: DB 21 ; text starting line number in splitscreen ;0 relative PEN_FLAG: DB 1 ; 0 if penup, 1 if pendown PEN_COLOR: DB WHITE ; Current pen color XOR_FLAG: DB 0 ; 1 if xor mode. 0 if normal mode CSEG ENTRY BEEP BEEP: PUSH BC LD C,2 LD E,7 CALL SYSTEM POP BC RET ; ================================================================== ; == INITIALIZATION AND MODE SETUP == ; ================================================================== ; initmode () /* Clears screen, sets borders, and */ ; /* initializes peripherals. */ ; { ; register int i; ; ; rslini(); /* move rom_call_routine to topmem, */ ; /* and initialize resolution. */ ; sndini(); /* stop sounds */ ; reset_pal(PALCOUNT); ; g_pal(1); ; c_pal(1); ; set_bord(0); ; clr_scrn(); ; txton(); /* select text plane */ ; for (i = 0; i < 0x7d0; ++i) ; vout(i,' '); /* clear character plane */ ; for (i = 0x800; i < 0x800+0x7d0; ++i) ; vout(i,7); /* clear attribute plane */ ; set_curs(0,0); ; } EXTRN RSLINI,CLEAN ENTRY INITMODE INITMODE: PUSH BC CALL RSLINI CALL SNDINI ; LD HL,PALCOUNT ; PUSH HL ; CALL RESET_PAL ; POP DE ; LD HL,1 ; PUSH HL ; PUSH HL ; CALL G_PAL ; POP DE ; CALL C_PAL ; POP DE XOR A OUT (BKDPPT),A CALL CLEAN CALL TXTON LD BC,0 LD A,' ' INITM1: OUT (C),A INC B JR NZ,INITM1 INC C BIT 3,C JR Z,INITM1 LD A,7 INITM2: OUT (C),A INC B JR NZ,INITM2 INC C BIT 4,C JR Z,INITM2 LD HL,0 ;CURSOR HOME CALL SET_CS ; LD C,33 ;CONTROL P DISABLE LD E,0 ; CALL SIMON ; POP BC RET ; grafmode () /* Sets resolution. */ ; { ; scrmod = GMOD; ; txtoff(); /* select transparent plane */ ; } ENTRY GRAFMODE GRAFMODE: LD A,GMOD LD (SCR_MOD),A JP TXTOFF ; textmode () /* Sets resolution, positions cursor to home.*/ ; { ; scrmod = TMOD; ; clr_back(2); /* clear background color black */ ; txton(); /* select test plane */ ; } ENTRY TEXTMODE TEXTMODE: PUSH BC LD A,TMOD LD (SCR_MOD),A LD A,10000B ;CLEAR BACKGROUND COLOR BLACK CALL CLR_BACK ; CALL TXTON POP BC RET ; splitmode () /* Sets resolution. */ ; { ; scrmod = SMOD; ; clr_back(0); /* clear background color transparent */ ; clear_wi(0,0,splittop-1,39); ; /* if (alphay < splittop) ; set_curs(splittop,0); */ ; txton(); /* select test plane */ ; } ENTRY SPLITMODE SPLITMODE: PUSH BC LD A,SMOD LD (SCR_MOD),A XOR A ;CLEAR BACKGROUND COLOR TRANSPARENT CALL CLR_BACK ; LD A,(SPLTTP) ;D := Y1, B := X1, E := Y2, C := WIDTH DEC A ; LD E,A ; LD BC,0*100H+40 ; LD D,0 ; CALL P,CLEAR0 ;CLEAR SCREEN IF NEEDED CALL TXTON POP BC RET ENTRY SCRMODE SCRMODE: LD a,(SCR_MOD) LD l,a LD h,0 OR a ret ; set_split (i) /* Sets the number of lines in the splitscreen's*/ ; int i; /* text window. */ ; { ; splittop = 25-i; ; } ENTRY SET_SPLIT SET_SPLIT: LD HL,2 ADD HL,SP LD A,(HL) DEC A ; Split line (0 relative) LD (SPLTTP),A ; RET ENTRY SPLITR SPLITR: LD A,(SPLTTP) INC A LD L,A LD H,0 OR A RET ; pendown () /* Sets penmode variable to not up. */ ; { ; pen_flag = DOWN; ; xor_flag = 0; ; } ; penup () /* Sets the penmode variable to up. */ ; { ; pen_flag = UP; ; xor_flag = 0; ; } ENTRY PEND ENTRY PENU PEND: LD A,PD LD (PEN_FLAG),A JP CLR_XOR PENU: LD A,PU ; LD (PEN_FLAG),A CLR_XOR: LD A,NORMALMOD LD (XOR_FLAG),A RET ; int down () /* Returns contents of penmode variable.*/ ; { ; return pen_flag; ; } ; setpc (p) /* Sets color veriable to input value. */ ; int p; ; { ; pen_color = p; ; } ENTRY SETP SETP: LD HL,2 ADD HL,SP LD A,(HL) LD (PEN_COLOR),A RET ; int getpc () /* Returns current value of pen color. */ ; { ; return pen_color; ; } ; ; reverse() /* Toggles XOR flag. */ ; { ; xor_flag ^= 1; ; } ENTRY REVERSE REVERSE: LD A,(XOR_FLAG) XOR 1 LD (XOR_FLAG),A RET ; set_bord (col) /* Sets border color. */ ; int col; ; { ; out(BORDPT,col); ; } ; int palmap[PALCOUNT][3]; ; /* R G B */ ; int palini[PALCOUNT][3]={{0, 0, 0}, /* black */ ; { 0, 0,15}, /* deep blue */ ; { 0,15, 0}, /* bright green */ ; { 0,15,15}, /* turquoise */ ; {15, 0, 0}, /* red */ ; {15, 0,15}, /* brilliant pink */ ; {15,15, 0}, /* yellow */ ; {15,15,15}, /* white */ ; { 3, 5, 4}, /* dark green */ ; { 3, 8, 4}, /* moss green */ ; {14, 6, 4}, /* salmon */ ; {14,10, 4}, /* tan */ ; { 3, 6, 9}, /* ash blue */ ; { 3,10,14}, /* light blue */ ; {15, 8,10}, /* pale pink */ ; { 8, 9, 9}}; /* gray */ ; set_pl (p, r, g, b) /* Sets palette. */ ; int p, r, g, b; ; { ; palmap[p][0] = r; ; palmap[p][1] = g; ; palmap[p][2] = b; ; stpal(p,palmap[p]); ; } IF FALSE ENTRY SET_PL SET_PL: CALL ISPALE ;DO NOTHING IF THERE'S NO PALETTE CIRCUIT RET NZ ; PUSH BC LD HL,4 ADD HL,SP LD A,(HL) ;A := PALETTE NUMBER PUSH AF ;SAVE IT ADD A,A ADD A,(HL) EX DE,HL ;DE := DESTINATION ADDRESS LD HL,PALMAP ; ADDHLA ; EX DE,HL ; PUSH DE LD B,3 SET_P1: INC HL INC HL LD A,(HL) LD (DE),A INC DE DJNZ SET_P1 POP HL ;HL := COLOR RATIO TABLE ADDRESS POP BC ;B := PALETTE# CALL STPAL POP BC RET ; reset_pal (p) /* Resets palette to initial color. */ ; int p; /* Resets all if p == 16. */ ; { ; register int i; ; ; if (p < PALCOUNT) ; res_pal(p); ; else ; for (i = 0; i < PALCOUNT; ++i) ; res_pal(i); ; } ENTRY RESET_PAL RESET_PAL: PUSH BC LD HL,4 ADD HL,SP LD A,(HL) CP PALCOUNT ;IF THE ARGUMENT WAS PALCOUNT, RESET ALL. JR NC,RP1 ; CALL RES_PAL POP BC RET RP1: XOR A PR2: PUSH AF CALL RES_PAL POP AF INC A CP PALCOUNT JR C,PR2 POP BC RET ; res_pal (p) ; int p; ; { ; register int k; ; static int *i, *j; ; ; i = palmap[p]; ; j = palini[p]; ; for (k = 0; k <= 2; ++k) ; *i++ = *j++; ; stpal(p,palmap[p]); ; } ; ACCEPTS A <= PALETTE# ENTRY RES_PAL RES_PAL: PUSH AF ;SAVE PALETTE# LD C,A ADD A,A ;HL := PALMAP + PALETTE# * 3 ADD A,C ; LD C,A ; LD HL,PALMAP ; ADDHLA ; PUSH HL ;SAVE PALMAP[PALETTE#] EX DE,HL LD A,C ;HL := PALINI[PALETTE#] LD HL,PALINI ; ADDHLA ; LD BC,3 ;COPY LDIR ; POP HL ;HL := COLOR MAPPING TABLE ADDRESS POP BC ;B := PALETTE# JP STPAL ; int *pal (p) /* Returns current color mapping. */ ; int p; ; { ; return palmap[p]; ; } ENTRY PAL PAL: PUSH BC LD HL,4 ADD HL,SP LD A,(HL) ADD A,A ADD A,(HL) LD HL,PALMAP ADDHLA LD DE,RETMAP PUSH DE LD BC,3*100H+0FFH XOR A PAL1: LDI LD (DE),A INC DE DJNZ PAL1 POP HL OR 0FFH POP BC RET ENDIF ; int ot_scr (x, y) /* Tests if out of screen */ ; int x, y; ; { ; return ( x < 0 || x > 319 || ; y < 1 || y > 200 ); ; } ENTRY OT_SCR OT_SCR: PUSH BC LD HL,4 ADD HL,SP LD E,(HL) ;DE := X INC HL ; LD D,(HL) ; INC HL ; LD C,(HL) ;BC := Y INC HL ; LD B,(HL) ; ; ; Changed by T.Hirayama Sept. 22, 1983 ; LD HL,199 OR A SBC HL,BC ; OTSCR0: POP BC JR C,OTSCR1 LD HL,319 ;319 - DE SBC HL,DE ; (CY == 0) JR C,OTSCR1 LD HL,0 AND L ;Z := 1 RET OTSCR1: LD HL,1 OR L ;Z := 0 RET ; ================================================================== ; == CHARACTER SCREEN INTERFACE == ; ================================================================== ; #define CR 0x0d ; #define LF 0x0a ; #define BS 0x08 ; ; con_out (c) /* Checks current mode, displays character at */ ; char c; /* current row and column, increments column. */ ; { ; static int i; ; ; /* switch (c) { ; case CR: ; set_curs(alphay,0); ; return; ; case LF: ; if (alphay < 24) ; set_curs(alphay+1,alphax); ; else { ; scrl_u(0,0,24,39); ; set_curs(24,alphax); ; } ; return; ; case BS: ; if (alphax > 0) { ; set_curs(alphay,alphax-1); ; return; ; } else if (alphay > 0) { ; set_curs(alphay-1,39); ; return; ; } ; break; ; default: ; break; ; } */ ; if (scrmod != SMOD || alphay >= splittop) { ; vout(i = chradr(alphay,alphax), c); ; vout(i+0x800,(scrmod == SMOD ? 0 : BLACKBACK)+bli+alphac); ; } ; set_curs(alphay,alphax+1); ; } ENTRY CON_OUT CON_OUT: PUSH BC LD HL,4 ADD HL,SP LD A,(HL) LD HL,(ALFAX) IF FALSE CP CR JR NZ,CONOU1 LD L,0 JP SET_C5 CONOU1: CP LF JR NZ,CONOU4 LD A,H CP 24 JR NC,CONOU2 INC H JP SET_C5 CONOU2: LD H,24 CALL SET_CS LD BC,0*100H+40 LD DE,0*100H+24 JP SCRL_1 CONOU4: CP BS JR NZ,CONOU7 INC L DEC L JR Z,CONOU5 DEC L JP SET_C5 CONOU5: INC H DEC H JR Z,CONOU6 DEC H LD L,39 JP SET_C5 CONOU6: POP BC RET CONOU7: ENDIF ;FALSE LD E,A ;E := CHARACTER CODE LD A,(SCR_MOD) CP SMOD JR NZ,CONO75 LD A,(SPLTTP) CP H JR Z,CONO75 JR NC,CONOU9 CONO75: LD A,L LD L,H LD H,A CALL CHRADR LD B,L LD C,H LD A,E OUT (C),A SET 3,C LD A,(SCR_MOD) CP SMOD LD E,0 JR Z,CONOU8 LD E,10000B ;background color := black CONOU8: LD A,(BLI) OR E LD E,A LD A,(ALFAC) OR E OUT (C),A CONOU9: LD HL,(ALFAX) INC L JP SET_C5 ; CLR_TSCRN(l,u); ENTRY CLR_TSCRN CLR_TSCRN: ; by T.Hirayama Sep. 26, 1983 push bc ld a,(SCR_MOD) cp GMOD ;Do not move cursor if graphic mode. jr z,CLEAR6 ; ld hl,0 ;Move cursor to (0,0) if text mode. cp TMOD ; jr z,CLEAR5 ; ld a,(SPLTTP) ;Move to (0,splittp) if text mode. ld h,a ; CLEAR5: ; call SET_CS ; CLEAR6: call SCRNBX ; SJS 01/11/84 ; ld bc,0*100h+40 ;Clear all of the screen. ; ld de,0*100h+24 ; ; ; LD A,(SCR_MOD) ;DO NOTHING IF CURRENT MODE IS GRAPHIC MODE ; CP GMOD ; ; RET Z ; ; PUSH BC ; LD HL,0 ;IF TEXT MODE H := 0 ELSE H := SPLITTOP ; CP TMOD ;L := 0 ; JR Z,CLEAR5 ; ; LD A,(SPLTTP) ; ; LD H,A ; ;CLEAR5: ; CALL SET_CS ; LD BC,0*100H+40 ; LD DE,0*100H+24 IF FALSE JR CLEAR9 ; clear_wi (y1, x1, y2, x2) /* Checks current mode, clears text screen,*/ ; int y1, x1, y2, x2; /* maintains cursor. */ ; { ; register int j; ; static int i, k, m; ; ; if (scrmod == GMOD) ; return; ; m = (scrmod == TMOD ? BLACKBACK : 0) + alphac; ; for (i = y1; i <= y2; ++i) ; for (j = x1; j <= x2; ++j) { ; vout(k = chradr(i,j),' '); ; vout(k+0x800,m); ; } ; } ENTRY CLEAR_WI CLEAR_WI: LD A,(SCR_MOD) ;DO NOTHING IF CURRENT MODE IS GRAPHIC MODE CP GMOD ; RET Z ; PUSH BC LD HL,4 ADD HL,SP CALL SCRNBX ;D := Y1, B := 0, E := Y2, C := WIDTH (40) CLEAR9: ENDIF ;FALSE CALL CLEAR0 POP BC RET CLEAR0: INC E LD A,(SCR_MOD) ;IF SCRMOD == TMOD, BACKGROUND COLOR := BLACK LD L,0 ;ELSE BACKGROUND COLOR := TRANSPARENT CP TMOD ; JR NZ,CLEAR1 ; LD L,10000B ; CLEAR1: LD A,(ALFAC) ;A' := ATTRIBUTE BYTE OR L ; EX AF,AF' ; CLEAR2: PUSH BC ;SAVE PARAMETERS PUSH DE ; LD H,B ;H := X1 LD L,D ;L := CURRENT Y LD B,C ;B := WIDTH CALL CHRADR LD A,' ' CLEAR3: PUSH BC ;DISPLAY CHARACTER AND ATTRIBUTE LD B,L ; LD C,H ; OUT (C),A ; SET 3,C ; EX AF,AF' ; OUT (C),A ; EX AF,AF' ; RES 3,C ; INC HL ; INC HL ; POP BC ; DJNZ CLEAR3 ;REPEAT B TIMES POP DE POP BC INC D LD A,D CP E JR NZ,CLEAR2 RET ; clr_back(i) ; int i; ; { ; register int j; ; static int k; ; ; k = i << 3; ; for (j = 0x800; j < 0x800+0x7d0; ++j, ++j) ; vout(j,(vin(j) & 0xe7) | k); ; } ; ACCEPTS A <= BACK MODE CLR_BACK: LD E,A LD BC,8+0*100H CLR_B1: IN A,(C) AND 11100111B OR E OUT (C),A INC B INC B JR NZ,CLR_B1 INC C BIT 4,C JR Z,CLR_B1 RET ; set_curs (row, col) /* Moves cursor to input row and column.*/ ; int row, col; ; { ; register unsigned i; ; ; alphax = col; ; alphay = row; ; if (alphax >= 40) { ; alphax -= 40; ; ++alphay; ; } ; if (alphay >= 25) { ; scrl_u(0,0,24,39); ; alphay = 24; ; } ; i = chradr(alphay,alphax); ; out(CRTCA,14); ; out(CRTCD,i>>8); ; out(CRTCA,15); ; out(CRTCD,i & 0xff); ; } ENTRY SET_CURS SET_CURS: PUSH BC LD HL,4 ADD HL,SP LD D,(HL) ;D := COLUMN DEC D ;MAKE 0 RELATIVE INC HL INC HL LD E,(HL) ;E := ROW DEC E ;MAKE 0 RELATIVE LD A,E SUB 40 JR C,SET_C1 LD D,A DEC E SET_C1: LD A,D CP 25 JR C,SET_C4 LD D,24 PUSH DE ; scrl_u(0,0,24,39); LD BC,0*100H+40 LD DE,0*100H+24 LD HL,SET_C3 PUSH HL PUSH HL JR SCRL_1 SET_C3: POP DE SET_C4: EX DE,HL SET_C5: CALL SET_CS POP BC RET ; L == X ; H == Y SET_CS: LD (ALFAX),HL LD A,H LD H,L LD L,A CALL CHRADR LD A,14 OUT (CRTCAD),A LD A,H OUT (CRTCDT),A LD A,15 OUT (CRTCAD),A LD A,L OUT (CRTCDT),A RET ; scrl_u (y1, x1, y2, x2) /* Moves text contained in input-specified */ ; int y1, x1, y2, x2; /* window up one line. */ ; { ; int vin(); ; register int j; ; static int i, k; ; ; /* Attributes are not scrolled up. */ ; for (i = y1; i < y2; ++i) ; for (j = x1; j <= x2; ++j) { ; k = chradr(i,j); ; vout(k,vin(k+80)); ; } ; for (j = x1; j <= x2; ++j) ; vout(chradr(y2,j),' '); ; } ENTRY SCRL_U SCRL_U: PUSH BC ; LD HL,4 ; ADD HL,SP ; ; LD BC,0*100H+40 ;SCROLL UP (0,0)-(39,24) IF TMODE OR GMODE. ; LD DE,0*100H+24 ;SCROLL UP (0,SPLTTP)-(39,24) IF SMODE. ; LD A,(SCR_MOD) ; ; CP SMOD ; ; JR NZ,SCRL_1 ; ; LD A,(SPLTTP) ; ; LD D,A CALL SCRNBX ;D := Y1 , B := X1 , E := Y2 , C := WIDTH LD A,D ;CHECK IF SCROLL AREA CONTAINS ONLY 1 LINE. CP E ; JR Z,SCRL_5 ; SCRL_1: PUSH BC ;SAVE X1 AND WIDTH SCRL_2: PUSH DE ;SAVE PARAMETERS PUSH BC ; LD H,B ;H := X1 LD L,D ;L := CURRENT Y LD B,C ;B := WIDTH CALL CHRADR ;DE := CHARACTER ADDRESS LD E,L ;HL := NEXT LINE LD D,H ; SET 3,D ; LD A,80 ; ADDHLA ; SCRL_3: PUSH BC ;MOVE UP 1 CHARACTER LD B,L ; LD C,H ; IN A,(C) ; EX AF,AF' ; SET 3,C ; IN A,(C) ; INC HL ; INC HL ; LD B,E ; LD C,D ; OUT (C),A ; RES 3,C ; EX AF,AF' ; OUT (C),A ; INC DE ; INC DE ; POP BC ; DJNZ SCRL_3 ;REPEAT B TIMES POP BC POP DE INC D LD A,D CP E JR NZ,SCRL_2 POP BC ;B := X1, C := WIDTH ; fill ' 's in last line SCRL_5: LD L,E ;L := Y2 LD H,B ;H := X1 LD E,C ;E := WIDTH CALL CHRADR LD A,' ' SCRL_6: LD B,L LD C,H OUT (C),A INC HL INC HL DEC E JR NZ,SCRL_6 POP BC RET ;D := Y1 , B := (0) , E := Y2 , C := 40 SCRNBX: LD HL,6 ; [ret] [bc] [SCRNBX ret] on stack ADD HL,SP LD D,(HL) ;D := Y1 DEC D ;MAKE 0 RELATIVE INC HL INC HL LD E,(HL) ;E := Y2 DEC E ;MAKE 0 RELATIVE LD BC,40 ;b := 0, c:= 40 RET ; int con_in () /* Returns character code if key hit. Returns*/ ; { /* 0 if not hit. */ ; while (! con_stat()) {} ; return bdos(6,0xff); ; } ENTRY CON_IN CON_IN: push bc ; Save bc as per 'C' calling convention --SJS con0: CALL CON_STAT JR Z,con0 LD C,6 ;DIRECT CONSOLE INPUT LD E,0FFH ; CALL SYSTEM ; CP ESC JR NZ,CONST1 IN A,(1BH) ;IF (1BH).7 == 1 THEN CTRL KEY PRESSED. ADD A,A ; LD A,ESC JR C,CONST1 XOR A JR CONST1 ; int con_stat () /* Returns 0 if console buffer empty. Returns*/ ; { /* non_0 if not empty. */ ; return (in(0x1b) & 1); ; } ENTRY CON_STAT CON_STAT: push bc ; --SJS IN A,(1BH) AND 1 ;Z IS RE/SET CONST1: LD L,A LD H,0 OR H pop bc ; restore bc for CON_IN and CON_STAT RET ; ================================================================== ; == MISCELLANEOUS SUBROUTINES == ; ================================================================== ; topofmem () ; { ; static unsigned *i; ; ; return *(i = 6); ; } ; int chradr (y, x) /* returns character address in (x y) */ ; int y, x; ; { ; return (x<<1)+(y*80); ; } ; ACCEPTS X IN H, Y IN L ; RETURNS I/O ADDRESS IN HL CHRADR: PUSH DE LD A,H LD H,0 ;HL := L * 40 ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; LD E,L ; LD D,H ; ADD HL,HL ; ADD HL,HL ; ADD HL,DE ; LD E,A ;HL += A LD D,0 ; ADD HL,DE ; ADD HL,HL POP DE RET ; txton () ; { ; out(CRTCA,10); ; out(CRTCD,0x67); ; out(CRTCA,11); ; out(CRTCD,0x07); ; out(0x20,TEXTPL); /* select test plane */ ; } ; ; txtoff () ; { ; out(CRTCA,10); ; out(CRTCD,0x27); ; out(CRTCA,11); ; out(CRTCD,0x07); ; out(0x20,TRANSPL); /* select transparent plane */ ; } ENTRY TXTON TXTON: LD HL,TEXTPL*100H+67H JR TXTOF1 ENTRY TXTOFF TXTOFF: LD HL,TRANSPL*100H+27H TXTOF1: LD A,H OUT (20H),A LD A,10 OUT (CRTCAD),A LD A,L OUT (CRTCDT),A LD A,11 OUT (CRTCAD),A LD A,07H OUT (CRTCDT),A RET ; ================================================================== ; == PRINTER I/O FUNCTIONS == ; ================================================================== ENTRY PRTREADY ENTRY PRT_CHAR ;-------------------------------- ; int prtread () ; return TRUE if printer ready else FALSE ;-------------------------------- PRTREADY: IN A,(1DH) AND 00010000B JR Z,PRTR1 LD HL,0 ;NOT READY AND L ;Z := 1 RET ; PRTR1: LD HL,1H ;READY OR L ;Z := 0 RET ; ;-------------------------------- ; prt_char (c) ; print out c ;-------------------------------- PRT_CHAR: IN A,(1DH) ;WAIT FOR PRINTER READY AND 00010000B ; JR NZ,PRT_CHAR ; LD HL,2 ;OUTPUT CHARACTER ADD HL,SP ; LD A,(HL) ; OUT (22H),A ; LD A,16H OUT (1CH),A LD A,06H OUT (1CH),A RET ; ================================================================== ; == GAME I/O FUNCTIONS == ; ================================================================== ENTRY JOYIN ENTRY BUTTON ENTRY TONES ENTRY SNDINI ;-------------------------------- ; int button (i) ; int i; paddle number <0..1> ; returns 1 if button[0] touched, 0 if not touched ;-------------------------------- BUTTON: CALL pdlsub AND 00010000b ;if a.4 == 0 then cy := 1 else cy := 0 LD A,0 JR NZ,joyin1 LD A,1 JR joyin1 ;-------------------------------- ; int joyin (i) ; int i; paddle number <0..1> ; RET : 0 (not pressed or illegal) ; ; 8 1 2 ; 7 + 3 ; 6 5 4 ; ;-------------------------------- joyin: CALL pdlsub AND 00001111b LD HL,pdltbl ADDHLA LD A,(HL) joyin1: OR A LD L,A LD H,0 RET pdltbl: DB 0 ;0000 ILLEGAL DB 0 ;0001 ILLEGAL DB 0 ;0010 ILLEGAL DB 0 ;0011 ILLEGAL DB 0 ;0100 ILLEGAL DB 4 ;0101 BACKWARD RIGHT DB 2 ;0110 FORWARD RIGHT DB 3 ;0111 RIGHT DB 0 ;1000 ILLEGAL DB 6 ;1001 BACKWARD LEFT DB 8 ;1010 FORWARD LEFT DB 7 ;1011 LEFT DB 0 ;1100 ILLEGAL DB 5 ;1101 BACKWARD DB 1 ;1110 FORWARD DB 0 ;1111 NOT TOUCHED ;-------------------------------- ; read paddle status ; RET A : read data ;-------------------------------- pdlsub: LD A,15H ;activate joystic port OUT (PADLPT),A ; PUSH BC LD HL,6 ADD HL,SP LD A,(HL) AND 00000001b ;b := 0, 1 CPL ; LD B,A ; LD C,PADLPT IN A,(C) POP BC RET MINATT EQU 15 ;MINIMUM ATTENUATION ENVTBL: DB MINATT- 4 ;**** 0 16 msec DB MINATT- 9 ;********* 1 16 msec DB MINATT-12 ;************ 2 16 msec DB MINATT-14 ;************** 3 16 msec DB MINATT-15 ;*************** 4 16 msec DB MINATT-15 ;*************** 5 16 msec DB MINATT-14 ;************** 6 16 msec DB MINATT-13 ;************* 7 16 msec ENVTBE EQU $ ENVTLN EQU ENVTBE-ENVTBL ;-------------------------------- ; tones (f, d) ; int f; hight <0..49> ; int d; duration ;-------------------------------- TONES: PUSH BC LD HL,4 ADD HL,SP LD C,(HL) ;c := hight INC HL INC HL LDHLHL ;HL := duration LD A,L ;do nothing if duration is 0 OR H ; JR Z,TONES9 ; INC C ;wait HL msec if hight == 0 DEC C ; JR Z,TONES8 ; PUSH HL ;save duration LD A,C ;set hight CALL SETHI ; LD E,L ;de := HL \ 16 LD D,H ; LD B,4 ; TONES2: SRL D ; RR E ; DJNZ TONES2 ; INC D ;de := MIN(de,ENVTLN) DEC D ; JR NZ,TONES3 ; LD A,E ; CP ENVTLN ; JR C,TONES4 ; TONES3: LD DE,ENVTLN ; TONES4: LD HL,ENVTBE ;de := ENVTBE - de OR A ;HL := duration SBC HL,DE ; EX DE,HL ; POP HL ; TONES5: PUSH HL ;sustain if end of table LD HL,ENVTBE ; OR A ; SBC HL,DE ; POP HL ; JR Z,TONES6 ; JR C,TONES6 ; LD A,(DE) ;a := attenuation CALL SETATT CALL WAI16M INC DE ;inc envelope table pointer LD A,L ;HL -= 16 SUB 16 ; JR NC,TONES5 ; DEC H ; JR TONES5 TONES6: LD A,MINATT-13 ;set final attenuation CALL SETATT ; TONES8: CALL WAIHLM ;sound length = HL msec LD A,10011111b ;tone 1 off OUT (PSGPT),A ; TONES9: POP BC RET PSGMAX EQU 2 ;PSG NUMBER = 0,1,2 ;-------------------------------- ; sound initialization ; initializes SN76489, ; clear sound, ;-------------------------------- SNDINI: LD A,11111111b ;noise off OUT (PSGPT),A ; ; disable all TONES LD A,10011111b ;tone 1 off OUT (PSGPT),A ; LD A,10111111b ;tone 2 off OUT (PSGPT),A ; LD A,11011111b ;tone 3 off OUT (PSGPT),A ; RET ;-------------------------------- ; set hight ; acc A : sound hight (1..49) ; dest A ;-------------------------------- SETHI: PUSH HL PUSH DE ; get tune LD D,0 CP OV1 JR NC,GETTU1 INC D CP OV2 JR NC,GETTU1 INC D CP OV3 JR NC,GETTU1 INC D GETTU1: LD HL,TUNTBL-1 ADDHLA LD L,(HL) LD H,D LD A,L LD D,L AND 11110000B LD L,A ;H := HL \ 16 ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; LD A,D AND 00001111B ; OUTPUT DATA OR 10000000b ;select tone 1 OUT (PSGPT),A LD A,H OUT (PSGPT),A POP DE POP HL RET ;-------------------------------- ; SET ATTENUATION ; ACC A : ATTENUATION ; DEST A,B ;-------------------------------- SETATT: OR 10010000b ;select tone 1 OUT (PSGPT),A RET ;-------------------------------- ; waits HL msec ; acc : HL duration ;-------------------------------- WAIHLM: PUSH HL JR wai161 ;-------------------------------- ; waits 16 msec ; acc : none ;-------------------------------- WAI16M: PUSH HL LD HL,16 ; following program section takes 1 msec. WAI161: CALL WAI1MS ;17 DEC HL ; 6 LD A,L ; 4 OR H ; 4 JR NZ,WAI161 ;12 POP HL RET ;-------------------------------- ; waits 1 msec ; acc : none ;-------------------------------- WAI1MS: PUSH AF ;11 LD A,248 ; 7 WAI1M1: DEC A ; 4 JR NZ,WAI1M1 ;12 POP AF ;10 RET ;10 ;-------------------------------- ; TUNE TABLE ;-------------------------------- TUNTBL: ; 3xx DB 0C2H ;C4 DB 08CH ;C4# DB 059H ;D4 DB 029H ;D4# OV3 EQU $-TUNTBL+1 ; 2xx DB 0FCH DB 0D1H DB 0A8H DB 082H DB 05EH DB 03CH DB 01CH DB 000H OV2 EQU $-TUNTBL+1 ; 1xx DB 0E1H ;C3 DB 0C6H DB 0ADH DB 094H DB 07EH DB 068H DB 054H DB 041H DB 02FH DB 01EH DB 00EH OV1 EQU $-TUNTBL+1 ; 0xx DB 0FFH DB 0F0H ;C2 DB 0E3H DB 0D6H DB 0CAH DB 0BFH DB 0B4H DB 0AAH DB 0A0H DB 097H DB 08FH DB 087H DB 07FH DB 078H ;C1 DB 071H DB 06BH DB 065H DB 05FH DB 05AH DB 055H DB 050H DB 04BH DB 047H DB 043H DB 03FH DB 03CH ;C0 TUNMAX EQU $-TUNTBL ; ================================================================== ; == PALETTE FUNCTIONS == ; ================================================================== IF FALSE ENTRY STPAL ; stpal (p,palmap) ; int p <0..15>; ; char palmap[3] <0..15>; ENTRY G_PAL ; g_pal (p) ; int p <0..1>; ENTRY C_PAL ; c_pal (p) ; int p <0..1>; ;-------------------------------- ; set palette ; B : PALETTE NUMBER [0..15] ; HL : (HL) == R, (HL+1) == G, (HL+2) == B [0..15] ;-------------------------------- STPAL: CALL ISPALE ;DO NOTHING IF THERE'S NO PALETTE RET NZ ; LD C,PLTDAT ;red CALL MAPOUT ; SET 4,B ;green CALL MAPOUT ; RES 4,B ;blue SET 5,B ; MAPOUT: LD A,(HL) ;e := color * 16 INC HL ;HL := next address REPT 4 ; ADD A,A ; ENDM ; LD E,A ; ;IN A,(1CH) ;do nothing palette circuit not mounted ;BIT 4,A ; ;RET NZ ; MAPOU1: IN A,(PLTMOD) ;loop while (pltmod).7 == 1 ADD A,A ; JR C,MAPOU1 ; OUT (C),E RET ;-------------------------------- ; IF THERE'S A PALETTE CARD THEN RETURN Z. ; ELSE RETURN NZ. ;-------------------------------- ISPALE: IN A,(1CH) AND 00010100B RET ;-------------------------------- ; control c_palette on/off ; arg1 : int i 1 for on, 0 for off ;-------------------------------- C_PAL: LD E,110b ;enbl/dsbl palette function of character plane DB 21h ; LD HL,nnnn ; falls through ;-------------------------------- ; control g_palette on/off ; arg1 : int i 1 for on, 0 for off ;-------------------------------- G_PAL: LD E,111b ;control graphics plane ad border area CALL ISPALE ;DO NOTHING IF THERE'S NO PALETTE CIRCUIT. RET NZ ; LD HL,2 ADD HL,SP LD A,(HL) ;if the argument is 0 then a := 0 OR A ;else a := 10000b JR Z,G_PAL1 ; LD A,10000b ; G_PAL1: OR E OUT (PLTMOD),A RET ; INITIAL COLOR MAPPING OF SMC05 ; ; NUMBER R G B (%) PALINI: DB 0, 0, 0 ; 0 0.0 0.0 0.0 DB 0, 0, 15 ; 1 0.0 0.0 100.0 DB 0, 15, 0 ; 2 0.0 100.0 0.0 DB 0, 15, 15 ; 3 0.0 100.0 100.0 DB 15, 0, 0 ; 4 100.0 0.0 0.0 DB 15, 0, 15 ; 5 100.0 0.0 100.0 DB 15, 15, 0 ; 6 100.0 100.0 0.0 DB 15, 15, 15 ; 7 100.0 100.0 100.0 DB 1, 4, 1 ; 8 22.9 36.0 23.7 DB 1, 7, 2 ; 9 22.9 50.2 25.2 DB 13, 5, 2 ; 10 92.9 41.4 23.8 DB 14, 9, 2 ; 11 94.1 64.6 25.4 DB 1, 5, 8 ; 12 23.0 42.0 62.4 DB 1, 9, 14 ; 13 23.1 66.6 94.1 DB 15, 7, 9 ; 14 98.7 50.5 64.6 DB 8, 8, 8 ; 15 55.7 57.0 58.8 ENDIF ; ================================================================== ; == ON_ROM ROUTINE CALLER == ; ================================================================== X1 equ 0ff44h Y1 equ 0ff46h RCALL macro adr CALL romcal dw adr endm extrn romcal ;-------------------------------- ; gwipe () ;-------------------------------- ENTRY GWIPE GWIPE: CALL @BCSAV XOR A ; a == color (1 byte width) RCALL 00FE7H ;-------------------------------- ; gplot (x, y) ;all are int ;-------------------------------- ENTRY GPLOT GPLOT: CALL @BCSAV CALL GPLOT0 ; HL == X ; DE == Y ; C == COLOR ; B == MODE RCALL 00F73H ;-------------------------------- ; gpnt(x, y) ;all are int ;-------------------------------- ENTRY GPNT GPNT: CALL @BCSAV CALL GPLOT0 ; HL == X ; DE == Y ; C == (not used) ; B == (not used) CALL GPOINT ; This subroutine returns (CY == 1, A == 0FFH) ; if out_of_screen. Otherwise, returns (CY==0) ; A = screen color (0..15) LD L,A ; HL := A LD H,0 ; JR NC,GPNT2 ; IF CY == 1 THEN HL := 0FFFFH LD H,A ; GPNT2: OR A RET GPOINT: RCALL 00F9FH ; Do ROMCALL -- pops this call's return addr. ; (Jan 13, 1984 -- SJS) ;-------------------------------- ; gline (x1, y1, x2, y2) ;all are int ;-------------------------------- ENTRY GLINE GLINE: CALL @BCSAV CALL GPLOTS ; HL == X ; DE == Y ; C == COLOR ; B == MODE RCALL 00E71H ; HL == address of 1st argument GPLOTS: LD E,(HL) ;set starting point INC HL ; LD D,(HL) ; INC HL ; LD (X1),DE ; LD E,(HL) ; INC HL ; LD D,(HL) ; INC HL ; PUSH HL ; LD HL,199 ; OR A ; SBC HL,DE ; LD (Y1),HL ; POP HL ; GPLOT0: LD B,2 ;save x and y GPLOT1: LD E,(HL) ; INC HL ; LD D,(HL) ; INC HL ; PUSH DE ; DJNZ GPLOT1 ; LD BC,(PEN_COLOR) ;C := COLOR , B := XOR FLAG INC B DEC B JR Z,GPLOT3 LD B,4 GPLOT3: ;LD C,(HL) ;c := color ;inc HL ; ;inc HL ; ;LD A,(HL) ;b := 0 (w/o) or 4 (xor) ;or A ;cy := 0 ;JR Z,GPLOT2 ; ;LD A,4 ; ;GPLOT2: LD B,A ; POP DE ;de := y LD HL,199 ; ; Add following instruction Sep. 26, 1983 T.Hirayama or a ;cy :=0 ; SBC HL,DE ;cy == 0 EX DE,HL ; POP HL ;HL := x RET ;-------------------------------- ; save bc ; HL := address of 1st argument ;-------------------------------- @BCSAV: POP HL ;HL := return address PUSH BC ;save bc LD BC,RSUMBC ;push address of resume bc PUSH BC ; PUSH HL ;save return address LD HL,8 ;HL := address of 1st argument ADD HL,SP ; RET RSUMBC: POP BC RET ; ================================================================== ; == I/O FUNCTIONS == ; ================================================================== ENTRY OUT ENTRY IN IF FALSE ; SJS 01/13 ENTRY VOUT ENTRY VIN ENDIF ;-------------------------------- ; out (adr, dat) ; char adr, dat; ;-------------------------------- OUT: PUSH BC LD HL,4 ADD HL,SP LD C,(HL) INC HL JR VOUT1 ;-------------------------------- ; int in (adr) ; char adr; ;-------------------------------- IN: PUSH BC LD HL,4 ADD HL,SP LD C,(HL) JP VIN1 ;-------------------------------- ; vout (adr, dat) ; int adr; ; char dat; ;-------------------------------- IF FALSE ;SJS VOUT: PUSH BC LD HL,4 ADD HL,SP LD B,(HL) ;cb := extended i/o address INC HL ; LD C,(HL) ; ENDIF VOUT1: INC HL ; LD A,(HL) ;a := output data OUT (C),A POP BC RET ;-------------------------------- ; int vin (adr) ; int adr; ;-------------------------------- IF FALSE VIN: PUSH BC LD HL,4 ADD HL,SP LD B,(HL) ;cb := extended i/o address INC HL ; LD C,(HL) ; ENDIF VIN1: IN A,(C) ;z is affected. POP BC LD L,A LD H,0 RET *include TURTLE.M80 END